Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.10.2014, 14:57   #71
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
По умолчанию

Немного отвлечёмся от класса Time

Ещё такое упражнение. К примеру, у меня есть класс "А", объект которого может хранить в себе целое число:

Код:
#include <iostream>

class A
{
public:
    A( int a = 0 ) : _a( a )
    {

    }

    int a() const
    {
        return _a;
    }

    void setA( int a )
    {
        _a = a;
    }

private:
    int _a;
};

int main()
{
    A myObject;
    myObject.setA( 10 );
    std::cout << "a = " << myObject.a() << std::endl;
    return 0;
}
А это тот же класс, но теперь он более универсальный. С помощью него я могу хранить не только целые числа, но даже строки:

Output:
Цитата:
int a = 10

float a = 10.5

double a = 10.5

std::string a = Hello, world!
Код:
#include <iostream>

template <typename T>
class A
{
public:
    A( T a ) : _a( a )
    {

    }

    T a() const
    {
        return _a;
    }

    void setA( T a )
    {
        _a = a;
    }

private:
    T _a;
};

int main()
{
    // Int
    A<int> intObject( 0 );
    intObject.setA( 10 );
    std::cout << "int a = " << intObject.a() << std::endl;
    std::cout << std::endl;

    // Float
    A<float> floatObject( 0.0f );
    floatObject.setA( 10.5f );
    std::cout << "float a = " << floatObject.a() << std::endl;
    std::cout << std::endl;

    // Double
    A<double> doubleObject( 0.0 );
    doubleObject.setA( 10.5 );
    std::cout << "double a = " << doubleObject.a() << std::endl;
    std::cout << std::endl;

    // String
    A<std::string> stringObject( "" );
    stringObject.setA( "Hello, world!" );
    std::cout << "std::string a = " << stringObject.a() << std::endl;
    std::cout << std::endl;
    return 0;
}
Теперь, собственно, упражнение. Реализуйте обобщённый класс Point, который может хранить x, y, z, как int, float и double по принципу выше

Последний раз редактировалось 8Observer8; 16.10.2014 в 15:59.
8Observer8 вне форума Ответить с цитированием
Старый 16.10.2014, 16:58   #72
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

У меня как раз тема Шаблоны и исключения)

Код:
#include <iostream>
#include <string>

template <class Type>
class Pointer
{
private:
    Type _a;
public:
    Pointer( Type a = 0 ) : _a(a)
    {}
    void setType(Type t)
    {
        _a = t;
    }
    Type a()
    {
        return _a;
    }
};

int main()
{
    Pointer <int> x;
    x.setType(2);
    std::cout << "int x = " << x.a();
    std::cout << std::endl;
    
    Pointer <float> y;
    y.setType(3.1f);
    std::cout << "float y = " << y.a();
    std::cout << std::endl;
    
    Pointer <double> z;
    z.setType(1.1);
    std::cout << "double z = " << z.a();
    std::cout << std::endl;
}
Вот: (сделал с сеттером)

Код:
#include <iostream>
#include <windows.h>
#include <process.h>
class Time
{
private:
    int _hour;
    int _min;
    int _sec;
public:
    Time(int h = 0, int m = 0, int s = 0) :
        _hour( h ), _min ( m ), _sec ( s ) {}
    int hour() const { return _hour; }
    int min() const { return _min; }
    int sec() const { return _sec; }
    void set_Time(int, int, int);
    void get_time();
    bool isHour () const { return (_hour >= 0 && _hour < 24); }
    bool isMin () const { return (_min >= 0 && _min < 60); }
    bool isSec () const { return (_sec >= 0 && _sec < 60); }
    Time& operator--();
    Time operator--( int );
    void sw () const
    {
        std::cout.fill('0');
        std::cout.width(2);
    }
    void tick();
};


Код:
void Time::set_Time(int h, int m, int s)
{
    _hour = h;
    _min = m;
    _sec = s;
}

Последний раз редактировалось Stilet; 18.10.2014 в 11:29.
igoreshka3333 вне форума Ответить с цитированием
Старый 16.10.2014, 18:18   #73
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
По умолчанию

Цитата:
Сообщение от igoreshka3333 Посмотреть сообщение
У меня как раз тема Шаблоны и исключения)

Код:
#include <iostream>
#include <string>

template <class Type>
class Pointer
{
private:
    Type _a;
public:
    Pointer( Type a = 0 ) : _a(a)
    {}
    void setType(Type t)
    {
        _a = t;
    }
    Type a()
    {
        return _a;
    }
};

int main()
{
    Pointer <int> x;
    x.setType(2);
    std::cout << "int x = " << x.a();
    std::cout << std::endl;
    
    Pointer <float> y;
    y.setType(3.1f);
    std::cout << "float y = " << y.a();
    std::cout << std::endl;
    
    Pointer <double> z;
    z.setType(1.1);
    std::cout << "double z = " << z.a();
    std::cout << std::endl;
}
Плоховато. Классы нужно делать, как можно ближе к жизни и удобству. Допустим, я к вам обращаюсь: сможете мне написать класс, в котором можно хранить координаты точки? Мы договариваемся о цене. Я вам плачу. Вы присылаете свой класс. Сначала я удивляюсь, почему для хранения координат точки используется класс с названием "Pointer"? "Pointer" переводится как указатель. Как "указатель" связан с "точкой"? И как вообще этот класс использовать? В следующий раз я не обращусь к такому исполнителю. Думайте перед тем как сделать следующий шаг

Удачное название для такого класса - это Point (переводится, как "точка"). У точки есть координаты: x, y, z

Вот как бы я хотел вывести координаты трёх точек на экран:
Код:
#include <iostream>
#include "Point.h"

int main()
{
    Point<float> point( 0.5f, 0.8f, 0.8f );

    std::cout << "x = " << point.x() << std::endl;
    std::cout << "y = " << point.y() << std::endl;
    std::cout << "z = " << point.z() << std::endl;
    std::cout << std::endl;

    return 0;
}
Упражнение. Перепишите класс, чтобы он удовлетворял требованиям выше
8Observer8 вне форума Ответить с цитированием
Старый 16.10.2014, 19:14   #74
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Спасибо! Исправил:

Код:
#include <iostream>
#include <string>

template <class Type>
class Point
{
private:
    Type _x;
    Type _y;
    Type _z;
public:
    Point( Type x = 0, Type y = 0, Type z = 0 ) :
        _x(x), _y(y), _z(z)
    {}
    void setPoint (Type x, Type y, Type z)
    {
        _x = x;
        _y = y;
        _z = z;
    }
    Type x() { return _x; }
    Type y() { return _y; }
    Type z() { return _z; }
};

int main()
{
    Point <int> point(1,2,3);
    std::cout << "x = " << point.x();
    std::cout << "\ny = " << point.y();
    std::cout << "\nz = " << point.z();
    std::cout << std::endl;

    Point <float> fpoint(1.1f, 2.2f, 2.3f);
    std::cout << "x = " << fpoint.x();
    std::cout << "\ny = " << fpoint.y();
    std::cout << "\nz = " << fpoint.z();
    std::cout << std::endl;

    Point <double> dpoint(1.1, 2.2, 2.3);
    std::cout << "x = " << dpoint.x();
    std::cout << "\ny = " << dpoint.y();
    std::cout << "\nz = " << dpoint.z();
    std::cout << std::endl;
    
    return 0;
}

Последний раз редактировалось igoreshka3333; 16.10.2014 в 19:22.
igoreshka3333 вне форума Ответить с цитированием
Старый 17.10.2014, 12:55   #75
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
Хорошо

Отлично!

Теперь вернёмся к классу Time. У вас уже есть система контроля ошибок. После нескольких упражнений я напишу о её главном недостатке - это дублирование кода, то есть строки "Wrong format!!!"

Упражнение. Сделайте систему контроля ошибок основанную на исключениях. Метод должен выбрасывать исключение класса std:ut_of_range

Пример того, как это должно выглядеть. Условие: калькулятор умеет делить вещественные числа, которые находятся в диапазоне (-100.0, 100.0). И осуществляет проверку деления на ноль. Если пользователь класса совершит ошибку, то программа об это сообщит:
Код:
#include <stdexcept>
#include <iostream>
#include <string>

class Calculator
{
public:
    double div( double a, double b )
        throw ( std::out_of_range, std::invalid_argument )
    {
        if ( b == 0.0 ) {
            throw std::invalid_argument( "Error: divide by zero" );
        }

        const double beginOfRange = -100.0;
        const double endOfRange = 100.0;

        if ( ( a <= beginOfRange ) || ( a >= endOfRange ) ||
             ( b <= beginOfRange ) || ( b >= endOfRange ) ) {
            throw std::out_of_range( "Error: argumets must be from the range ("
                                     + std::to_string( beginOfRange ) +
                                     ", " + std::to_string( endOfRange ) + ")");
        }

        return a / b;
    }
};

int main()
{
    Calculator calculator;

    try {
        double result = calculator.div( 24.0, 3.0 );
        std::cout << "result = " << result << std::endl;
    } catch ( const std::logic_error &e ) {
        std::cerr << e.what() << std::endl;
        return 1;
    } catch( ... ) {
        std::cerr << "Error: unknown exception" << std::endl;
        return 1;
    }

    return 0;
}
Сразу оговорюсь, что этот подход не решает главной проблемы: дублирования кода. А именно, дублирование строки, которая описывает ошибку "Error: argumets must be..." Если вы захотите изменить текст ошибки, на пример, вместо "must be" написать "should be", то придётся это делать в каждой функции, которая выбрасывает std:ut_of_range
(это конечно, можно сделать с помощью "Find And Replace", но не всегда это получится, и нужно будет вручную менять). Дублирование нужно избегать. Но есть продолжения, к котором приходят исключения - это классы исключений, и они решают проблему дублирования. О классах исключений - позже

Код:
catch ( const std::logic_error &e )
Так мы отлавливаем оба исключения: std:ut_of_range и std::invalid_argument, потому что они оба наследуются от std::logic_error. Доступ к объектам-наследникам через родительский класс - это полиморфизм

Последний раз редактировалось Stilet; 18.10.2014 в 11:29.
8Observer8 вне форума Ответить с цитированием
Старый 17.10.2014, 17:28   #76
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Вроде бы все ясно - попробую! Но решил протестировать новую для себя функцию to_string()
Код:
#include <iostream>
#include <string>

int main()
{
    const int val = 50;
    std::cout << std::to_string(val) << std::endl;
    return 0;
}
но компилятору это не понравилось!
igoreshka3333 вне форума Ответить с цитированием
Старый 17.10.2014, 17:32   #77
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
По умолчанию

С++ он тоже разный. У вас, скорее всего, С++98. А это из С++11. Совсем недавно ещё появился C++14

Если вы пишите в Qt Creator, то в профайле надо добавить:
Код:
CONFIG += console c++11

Последний раз редактировалось 8Observer8; 17.10.2014 в 17:39.
8Observer8 вне форума Ответить с цитированием
Старый 17.10.2014, 18:18   #78
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Цитата:
CONFIG += console c++11
Заработало!
igoreshka3333 вне форума Ответить с цитированием
Старый 17.10.2014, 19:32   #79
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
По умолчанию

Когда вы знаете, что есть функции, которые переводят числа в строки и обратно, то проще всего вспомнить хотя бы одну, набрать в гугле и выйти на подобную страницу с примером: http://www.cplusplus.com/reference/string/stoi/

А там уже на панели слева найти нужную. Думаю, так все делают.

Если не помните название, то набирайте: как перевести число и т.д. Тогда в примерах можно найти нужное название и уже потом перейти на сайт www.cplusplus.com. Там самая лучшая справка по всем классам C++

Заметьте, что когда std::stoi переводит из строки в целое и не может этого сделать (если пользователь ввёл слишком длинное число или буквы вместо числа), то эта функция выбрасывает исключение типов, соответственно, std::out_of_range и std::invalid_argument Они наследуются от std::logic_error, как видно из диаграммы наследования: http://www.cplusplus.com/reference/s...t/logic_error/

Сохраните себе пример, как переводить целые (вещественные) в строки и обратно:
Код:
#include <string>
#include <stdexcept>
#include <iostream>

int main()
{
    std::string str;
    std::string output;

    try {
        std::cout << "\nEnter an integer number:\n> ";
        std::getline( std::cin, str );

        int intN = stoi( str );
        output = "You wrote " + std::to_string( intN );
        std::cout << output << std::endl;

        std::cout << "\nEnter a real number:\n> ";
        std::getline( std::cin, str );
        float floatN = stof( str );
        output = "You wrote " + std::to_string( floatN );
        std::cout << output << std::endl;

        std::cout << "\nEnter a real number:\n> ";
        std::getline( std::cin, str );
        double doubleN = stod( str );
        output = "You wrote " + std::to_string( doubleN );
        std::cout << output << std::endl;
    } catch ( const std::logic_error ) {
        std::cerr << "Error: you wrote the incorrect number." << std::endl;
        return 1;
    } catch ( ... ) {
        std::cerr << "Error: unknown exception" << std::endl;
        return 1;
    }

    return 0;
}
Я из этой книги узнал, а именно из этого текста:

Примечание. Можете здесь её скачать: https://yadi.sk/d/VCvsky11c6wtP

"Chapter 14. Using String and Regular Expressions" -> "Dynamic Strings" -> "The C++ string Class"



Последний раз редактировалось 8Observer8; 18.10.2014 в 11:22.
8Observer8 вне форума Ответить с цитированием
Старый 17.10.2014, 20:03   #80
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Спасибо) Весьма полезно!
А что это за метод - в гугле не нашел (может и искал плохо)?
Цитата:
what()

Последний раз редактировалось igoreshka3333; 17.10.2014 в 20:06.
igoreshka3333 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
описать класс в с# volkodinocka Помощь студентам 0 09.11.2013 22:05
Описать класс С# NeoX_2011 Помощь студентам 1 19.03.2012 00:10
C# исправление ошибки. Описать класс, реализующий шестнадцатеричный счетчик PROkaZZZniK Помощь студентам 7 09.02.2012 16:29
Описать класс-родитель и класс-потомок. Delphi 7 Andrew_M Помощь студентам 0 15.01.2011 14:42
Описать класс. Telec Общие вопросы C/C++ 1 30.04.2010 18:43