Почему результат этой программы 3 "рожденных"? И 4 мертвых - PullRequest
0 голосов
/ 16 февраля 2020

Это главное. cpp:

int main() {

    Person arr[2] = {
        Person(18,180),
        Person(20,173)
    };
    arr[0]+arr[1];

    return 0;
}  

Это Person.h:

class Person
{
private:
    int age;
    int height;
public:
    Person(int age=20,int height=180);
    ~Person();
    void operator+(Person);
};

А это Person. cpp:



Person::Person(int age,int height) {
    (*this).age = age;
    (*this).height = height;
    cout << "I'm born.\n";
}

Person::~Person() {
    cout << "I'm dead.\n";
}

void Person::operator+(Person a) {
    Person result;
    result.age = (*this).age + a.age;
    result.height = (*this).height + a.height;
    cout << result.age << endl;
    cout << result.height << endl;
}

Почему результат этой программы 3 "рожденных"? И 4 мертвых? Каковы процедуры инициализации массива объектов 'arr'?

Ответы [ 3 ]

1 голос
/ 16 февраля 2020

В operator+ второй аргумент сложения, который является первым параметром, передается по значению и поэтому называется конструктором копирования (который не переопределяется, и поэтому вы не отслеживаете сборку объекта с помощью это) для того, чтобы построить его, и поэтому в конце вызова функции этот объект разрушается (и это ваш четвертый «скрытый» мертвец)

0 голосов
/ 16 февраля 2020

Давайте; посчитаем вместе количество вызовов конструктора и деструктора.

В этом объявлении массива

Person arr[2] = {
    Person(18,180),
    Person(20,173)
};

конструктор вызывается два раза, потому что два объекта класса создается Здесь происходит исключение вызовов конструктора копирования.

В этом вызове

arr[0]+arr[1];

используется следующая функция

void Person::operator+(Person a) {
    Person result;
    result.age = (*this).age + a.age;
    result.height = (*this).height + a.height;
    cout << result.age << endl;
    cout << result.height << endl;
}

Аргумент arr [ 1] передается функции по значению, вызывающему неявно определенный конструктор копирования. Таким образом, создается третий объект класса.

Внутри функции в этом объявлении создан четвертый объект

    Person result;

Итак, четыре объекта были созданы, три из них с использованием конструктора с параметрами и один с конструктором копирования. В результате были также вызваны четыре деструктора.

Оператор должен быть объявлен и определен, по крайней мере, как

Person Person::operator +( const Person &a) const {
    return Person( age + a.age, height + a.height );
}

С другой стороны, лучше сделать конструктор явным. Например

explicit Person(int age=20,int height=180) : age( age ), height( height )
{
}
0 голосов
/ 16 февраля 2020

Пропавший рожденный человек - это клон! Примечание operator+ принимает аргумент по значению, поэтому вызывается конструктор копирования (в данном случае по умолчанию). Чтобы увидеть это, добавьте

Person::Person(const Person &p) {
    this->age = p.age;
    this->height = p.height;
    cout << "I'm a clone.\n";
}

к своему коду - тогда понятно, почему в итоге погибли 4 человека. Лучше всего, чтобы у вас был странный оператор, чтобы иметь эту подпись, чтобы избежать копий и быть явным:

void Person::operator+(const Person &a) const;

Кроме того, нет смысла использовать *this, когда у вас есть оператор стрелки.

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