Объект сбрасывается при передаче в c ++ - PullRequest
4 голосов
/ 28 марта 2020

Я практиковал с ++ в последнее время и столкнулся с этим упражнением, в котором я немного борюсь со ссылкой на объекты.

Вот мой код:

ClockUT C .h

#include "ClockUTC.h"

ClockUTC::ClockUTC()
{
    hour = 0;
    minute = 0;
}

ClockUTC::ClockUTC(int hour, int minute)
{
    this-> hour = hour;
    this-> minute = minute;
}

int ClockUTC::getHour()
{
    return hour;
}

int ClockUTC::getMinute()
{
    return minute;
}

void ClockUTC::setHour(int hour)
{
    this->hour = hour;
}

void ClockUTC::setMinute(int minute)
{
    this->minute = minute;
}

ClockUT C. cpp

#ifndef CLOCKUTC_H_INCLUDED
#define CLOCKUTC_H_INCLUDED


#include <iostream>


using namespace std;



class ClockUTC {

private:
int hour;
int minute;

public:
    ClockUTC();
    ClockUTC(int hour, int minute);
    int getHour();
    int getMinute();
    void setHour(int hour);
    void setMinute(int minute);
};


#endif // CLOCKUTC_H_INCLUDED

ClockTZ.h

#ifndef CLOCKTZ_H_INCLUDED
#define CLOCKTZ_H_INCLUDED



#include <iostream>
#include "ClockUTC.h"


using namespace std;



class ClockTZ : public ClockUTC{

private:
ClockUTC clockUTC;
int offset;

public:
    ClockTZ(ClockUTC clockUTC, int offset);
    ClockUTC getClockUTC();
    int getOffset();
    void setClockUTC(ClockUTC clockUTC);
    void setOffset(int offset);
};




#endif // CLOCKTZ_H_INCLUDED

ClockTZ. cpp

#include "ClockTZ.h"


 ClockTZ::ClockTZ(ClockUTC clockUTC, int offset)
{
    this->clockUTC = clockUTC;
    this->offset = offset;
    clockUTC.setHour(clockUTC.getHour() + offset);
}


ClockUTC ClockTZ::getClockUTC()
{
    return clockUTC;
}


int ClockTZ::getOffset()
{
    return offset;
}


void ClockTZ::setClockUTC(ClockUTC clockUTC)
{
    this->clockUTC = clockUTC;
}



void ClockTZ::setOffset(int offset)
{
    this->offset = offset;
}

А вот основной файл:

/**
   Unit tests for 2nd EOOP assignment.

   ClockUTC - aggregate 2 integers (hour, minute)
   ClockTZ - view for ClockUTC, store reference to clockUTZ and offset

   Note that this is in a big part "code reading" exercise.
   Based on this file you should implement two classes mentioned above,
   with proper interface, and in right header file.
 */

    #include "ClockTZ.h"
    #include <iostream>

    using namespace std;

    int main() {

        ClockUTC greenwich(9,17);
        ClockTZ warsaw(greenwich, 2);

        if (warsaw.getHour() != 11){
            cout << "Error in getHour() 1" <<  endl;
        }

        return 0;
    }

Я закодировал вышеуказанные файлы, и единственная проблема - после создания Класс ClockUT C и передача его в ClockTZ, ClockUT C сбрасывает и вызывает пустой конструктор и устанавливает для часа значение 0 вместо значения + смещение, как и предполагалось. Я знаю, что это потому, что объект не имеет какой-либо ссылки, и он уничтожается, как только пройдет, или что-то в этом роде, но, кажется, не может это исправить.

Возможно, проблема в том, что ClockTZ имеет два объекта ClockUT C: базовый класс и переменная-член с именем clockUT C. Конструктор ClockTZ инициализирует переменную-член путем копирования переданного значения и по умолчанию инициализирует базовый класс. Когда я позже вызываю getHour, вызывается базовый класс, возвращая значение по умолчанию, равное 0.

Но в этом случае мне нужны оба ...

Токовый выход: 0

Ожидаемый результат: 11

Я пытался исправить это, используя & ссылку, но, похоже, ничего не работает. Может ли кто-нибудь помочь мне правильно его применить?

Вот что я пробовал: ClockUTC &clockUTC; как член класса (поэтому конструктор также должен будет принять параметр ClockUT C в качестве ссылки, тогда я использовал список инициализаторов-членов для его инициализации.

Как в коде:

ClockUT C & clockUTC;

ClockTZ (ClockUT C & clockUT C, int смещение);

ClockTZ :: ClockTZ (ClockUTC & _clockUT C, int _offset): clockUT C (_clockUT C), смещение (_offset) {}

Но это ничего не изменило, и я все еще получаю тот же вывод. Пожалуйста, кто-нибудь, помогите мне заставить его работать!

Обновление:

int main() {

    ClockUTC greenwich(9,17);
    ClockTZ warsaw(greenwich, 2);


    if (warsaw.getHour() != 11)
        cout << "Error in getHour() 1  warsaw " << warsaw.getHour() <<  endl;

    greenwich.setHour(11);

    if (warsaw.getHour() != 13)
        cout << "Error in getHour() 2 warsaw " << warsaw.getHour() << endl;


    cout << "End of tests." << endl;
    return 0;
}

Ожидаемый результат: 11, а затем 13, но он всегда будет 11. Поэтому ссылка не работает.

Мой конструктор:

ClockTZ::ClockTZ(ClockUTC clockUTC, int offset)
       : ClockUTC{clockUTC}
{
      this->offset = offset;
      clockUTC.setHour(clockUTC.getHour() + offset);
}

Теперь вывод будет всегда быть 9

1 Ответ

3 голосов
/ 28 марта 2020
class ClockTZ : public ClockUTC{

private:
   ClockUTC clockUTC;

Это неправильно. ClockTZ наследуется от ClockUTC. Он не должен иметь другого экземпляра ClockUTC в качестве члена класса. Это создает дубликат экземпляра ClockUTC, который является частным членом класса, в дополнение к наследованию от ClockUTC. Удалите этого clockUTC члена класса полностью. Просто избавьтесь от объявления clockUTC во всей его полноте.

ClockTZ::ClockTZ(ClockUTC clockUTC, int offset)
{
    this->clockUTC = clockUTC;

Вместо этого конструктор дочернего класса должен правильно создать свой родительский класс:

ClockTZ::ClockTZ(ClockUTC clockUTC, int offset)
       : ClockUTC{clockUTC}
{

Вот и все (или, может быть "ClockUTC(clockUTC)", если вы используете старый компилятор).

и он вызывает пустой конструктор и устанавливает для часа значение 0 вместо значения + смещение, как и предполагалось.

Конечно, это так. Ваш дочерний класс никогда не вызывает конструктор родительского класса, а вместо этого создает дубликат члена дочернего класса, который оказывается тем же классом, что и его родительский класс.

Ваша книга C ++ должна содержать больше информации и примеров правильного конструирование родительских классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...