用于赋值的参数化构造函数

Ovi*_*sca 3 c++ oop c++11

我注意到一些我在参数化构造函数中无法理解的行为.鉴于以下计划:

#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;
}
Run Code Online (Sandbox Code Playgroud)

我得到输出:

A
dA
3
A
dA
5
dA
Run Code Online (Sandbox Code Playgroud)

这意味着使用=触发器参数化构造函数,销毁它所调用的对象并创建一个新对象.我无法理解这种行为,我无法在标准中找到答案(我确信它存在于某个地方,但可能以复杂的方式陈述).有人可以帮我解释一下吗?

Som*_*ude 5

有一个声明

p = 3;
Run Code Online (Sandbox Code Playgroud)

你真正在做的是

p = A(3);
Run Code Online (Sandbox Code Playgroud)

这实际上转化为

p.operator=(A(3));
Run Code Online (Sandbox Code Playgroud)

当然,A创建的临时对象A(3)需要被破坏,毕竟它是暂时的.

对象p本身不会被赋值破坏.


mol*_*ilo 5

您可能正在寻找的短语是"隐式转换".

如果添加复制构造函数和赋值运算符,然后为每个对象提供唯一的ID,则更容易看到事情的进展:

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";
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

如您所见,参数化构造函数用于创建可以分配其值的临时对象p,并在此之后立即销毁该临时对象.
你也可以看到它还p活着,直到最后.