Почему конструктор и деструктор вызываются при назначении значения объекту - PullRequest
3 голосов
/ 05 июля 2019

У меня есть следующий код:

#include <iostream>

using namespace std;

class A{
    int x;
public:
    A(int x =1) : x(x) {cout << "A() ";}
    A(const A& a) {x =a.x; cout << "A(const A&) ";}
    A& operator=(const A& a){cout << "op= "; x=a.x; return *this;}
    ~A(){cout << "~A()";}
    int getX() {return x;}
    void setX(int x){this->x = x;}
};


A g(A a){
    //a = 2;
    cout << "g() ";
    a.setX(3);
    return a;
}

int main()
{
    A a;
    a = 2;

}

Я ожидал получить следующий вывод: A() op= ~A(), но вместо этого вывод A() A() op= ~A() ~A(). Кажется, конструктор и деструктор вызываются, когда я присваиваю значение 2 объекту a. Почему эти двое называются? Эффективно ли компилятор создает новый объект A с x = 2, а затем использует оператор присваивания для присвоения значения a?

1 Ответ

6 голосов
/ 05 июля 2019

Это потому, что вы не объявили оператор присваивания для вашего класса, который будет принимать int в качестве аргумента.Поскольку такого оператора не существует, компилятору необходимо использовать обходной путь: он создает временный объект, используя конструктор A (int).Вы можете избежать такого поведения, сделав конструктор явным:

explicit A(int x_ = 1) : x(x_) { }

После создания временного объекта он копируется в 'a', используя предоставленный конструктор копирования для A. Сразу после этого временный объект уничтожается и вызываетего деструктор.

Этот подход неэффективен.Чтобы сделать его лучше, вы должны определить оператор присваивания для A, взяв в качестве аргумента int:

A& operator= (int x_) {
    x = x_;
    return *this;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...