Параметризованный конструктор для присваивания - PullRequest
0 голосов
/ 07 июня 2018

Я заметил некоторое поведение, которое я не могу понять в параметризованных конструкторах.Учитывая следующую программу:

#include <iostream>
using namespace std;

class A {
public:
    int x;

    A() {}

    A(int i) : x(i){
        cout << "A\n";
    }
    ~A(){
        cout << "dA\n";
    }

};

int main(){
    A p;
    p = 3;
    cout << p.x << endl;
    p = 5;
    cout << p.x << endl;
    return 0;
}

Я получаю в качестве вывода:

A
dA
3
A
dA
5
dA

Это означает, что использование = запускает параметризованный конструктор, уничтожает объект, для которого он вызывается, и создаетновый объектЯ не могу понять это поведение, и я не могу найти ответ в стандарте (я уверен, что он где-то есть, но он может быть изложен изощренным способом).Может ли кто-нибудь помочь мне с объяснением?

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Фраза, которую вы, вероятно, ищете, это "неявное преобразование".

Если вы добавите конструктор копирования и оператор присваивания, а затем дадите каждому объекту уникальный идентификатор, вам будет легче увидеть, куда идут вещи:

int counter = 0;

class A {
public:
    int id;

    A(): id(++counter) {cout << "A(): " << id << "\n";}

    A(int i) : id(++counter) {cout << "A(" << i << "): " << id << "\n";}

    // Don't copy the id.
    // (This isn't used anywhere, but you can't see that it's not used unless it exists.)
    A(const A& a) : id(++counter) {cout << "A(" << a.id << "): " << id << "\n";}

    // Don't copy the id here either.
    A& operator=(const A&a) {cout << id << " = " << a.id << "\n"; return *this;}

    ~A(){cout << "destroy: " << id << "\n";}
};

int main(){
    A p;
    cout << "p is " << p.id << "\n";
    p = 3;
    cout << "p is " << p.id << "\n";    
    p = 5;
    cout << p.id << "\n";
}

Вывод:

A(): 1
p is 1
A(3): 2
1 = 2
destroy: 2
p is 1
A(5): 3
1 = 3
destroy: 3
1
destroy: 1

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

0 голосов
/ 07 июня 2018

С таким утверждением, как

p = 3;

, что вы на самом деле делаете, это

p = A(3);

, что на самом деле означает

p.operator=(A(3));

Временное Aобъект, созданный A(3), конечно же, должен быть уничтожен, в конце концов, он временный .

Сам объект p не будет разрушен назначением.

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