Правильно ли объявлять функцию с использованием членов класса?

0

Я пытаюсь преобразовать C-программу, используя struct в C++ с class es. Я пытаюсь вызвать функцию-член class B из class A Вот фрагмент, объясняющий мою ошибку:

    class Time{
        public:
        Time();
        Time(int hour, int minute);
        int time_Equal(Time &a, Time &b) const;
        -----
        private:
        int hour;
        int minute;
    };

    Boolean Time::time_Equal(Time &a, Time &b) const
    {
        /* If hour of Time "a" equals hour of Time "b" */
        if(a.hour == b.hour){
            if(a.minute == b.minute)
                    return TRUE;
        }
    }

    class DaTime{
        public:
        DaTime();
        DaTime(Day day, Time start, Time end);
        Boolean dt_Equal(DaTime &a, DaTime &b) const;

        private:
        int duration;
        Time start;
        Time end;
    };

    Boolean DaTime::dt_Equal(DaTime &a, DaTime &b) const
    {
            if(time_Equal(a.start, b.start)){
                   if(time_Equal(b.end, a.end))
                          return TRUE;
            }

            else
                    return FALSE;        
    }

Ошибка, которую я получаю, заключается в том, что time_Equal не объявляется в этой области. Причина, по которой я не понимаю этого, состоит в том, что я включил заголовочный файл, в котором Time объявлено перед DaTime. Я не вижу проблемы с тем, как я объявил функции.

  • 0
    time_Equal является членом Time , ни DaTime . Кроме того, что такое Boolean ? Это так же, как int ? Ваши определения должны соответствовать вашим декларациям.
  • 0
    Булево определено ранее. Он определяется как TRUE == 1 и FALSE == 0 .
Показать ещё 3 комментария
Теги:
class
declaration

3 ответа

3
Лучший ответ

Во-первых, обратите внимание, что тип boolean - это просто bool.

Во-вторых, возвращаемый тип объявления time_Equal является int, тогда как определение имеет Boolean. Довольно уверен, что вы хотите, чтобы оба были bool. Они должны по крайней мере соответствовать.

В-третьих, ваша функция time_Equal не изменяет свои аргументы, поэтому вы должны сделать их const ссылками (const Time &a и const Time &b).

В-четвертых, ваша функция time_Equal является time_Equal членом Time, но не использует ни одного из ее членов. То есть его вывод зависит только от его аргументов, а не от объекта, на который this указывает. Это запах кода. Это означает, что ваша функция должна быть, вероятно, статическая функция или вы должны изменить функцию, чтобы использовать this. Таким образом, у вас есть два варианта:

  1. Держите его членом и меняйте его:

    bool time_Equal(const Time &other) const;
    

    А затем в реализации вы должны сравнить *this с other аргументом. В этом случае вы бы назвали его как a.start.time_Equal(b.start).

  2. Сделайте его static членом или вынесите его из класса и сделайте его функцией друга и сохраните его с двумя аргументами:

    bool time_Equal(const Time &a, const Time &b) const;
    

    В этом случае вы называете это time_Equal(a.start, b.start).

В-пятых, C++ имеет встроенный оператор для выполнения теста для равенства (==), который вы можете перегрузить для класса. Таким образом, вы можете фактически реализовать указанные выше два варианта:

bool operator==(const Time &other) const; // As a non-static member
// or
bool operator==(const Time &a, const Time &b) const; // As a static member or friend function

Затем вы можете сравнить такие времена: a.start == b.start. Приятно, да?

Для получения дополнительной информации см. Часто задаваемые вопросы о перегрузке оператора.

В-шестых, ваша реализация time_Equal не возвращает false когда это необходимо. Вы можете легко переписать тело как:

return a.hour == b.hour && a.minute == b.minute;
  • 0
    Вау, спасибо за такое подробное объяснение, включая альтернативные варианты.
  • 0
    @AllenS Я, наверное, должен упомянуть, что operator== Friend Friend operator== перегрузка обычно предпочтительнее.
Показать ещё 1 комментарий
1

Функция time_Equal объявляется как нестатическая функция-член класса. Поэтому его можно использовать только с экземпляром класса. Более того, он объявлен как имеющий параметры типа Time. Однако в функции dt_Equal вы называете это передаваемыми аргументами типа int

        if(time_Equal(a.start, b.start)){
               if(time_Equal(b.end, a.end))
                      return TRUE;
        }

Вы должны объявить функцию time_Equal либо как не-членную функцию с двумя параметрами, либо как функцию-член с одним параметром.

Как функция-член, он может выглядеть так:

bool Time::time_Equal( const Time &rhs ) const
{
    return (  hour == rhs.hour  && minute == rhs.minute );
}

В качестве функции, не являющейся членом, она должна быть объявлена как функция друга класса, потому что члены часов час и минута определяются как частные или если у вас есть получатели на час и минуту, тогда нет необходимости делать это другом. В любом случае это может выглядеть так:

bool Time::time_Equal( const Time &lhs, const Time &rhs )
{
    return (  lhs.hour == rhs.hour  && lhs.minute == rhs.minute );
    // or return (  lhs.get_hour() == rhs.get_hour()  && lhs.get_minute() == rhs.get_minute() );

}
0

time_Equal - это метод в классе Time, но вы называете его глобальным. На объект должен вызываться метод уровня экземпляра.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню