堆栈上的构造函数/析构函数调用顺序

Sol*_*Sun 5 c++ constructor destructor assignment-operator

我有以下简单的代码:

class A
{
    int a;
public:
    A(int a) : a(a) { cout << "Constructor a=" << a << endl; }
    ~A()            { cout << "Destructor  a=" << a << endl; }
    void print()    { cout << "Print       a=" << a << endl; }
};

void f()
{
    A a(1);
    a.print();
    a = A(2);
    a.print();
}

int main()
{
    f();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Constructor a=1
Print       a=1
Constructor a=2
Destructor  a=2
Print       a=2
Destructor  a=2
Run Code Online (Sandbox Code Playgroud)

我发现有两个析构函数调用with a=2和none,a=1而每个case都有一个构造函数调用.那么在这种情况下如何调用构造函数和析构函数?

ale*_*der 7

a = A(2);
Run Code Online (Sandbox Code Playgroud)

将使用默认operator=值为其分配新值a,将其a::a成员值设置为2.

void f()
{
    A a(1);//a created with int constructor a.a == 1
    a.print();// print with a.a == 1
    a = A(2);//Another A created with int constructor setting a.a == 2 and immediately assigning that object to a
    //object created with A(2) deleted printing 2 it was created with
    a.print();//a.a==2 after assign
}//a deleted printing 2 it was assigned with
Run Code Online (Sandbox Code Playgroud)

您可能应该阅读有关三法则的内容,以便更好地了解正在发生的事情.


Vyk*_*tor 2

这是因为您没有破坏A(1)您正在分配A(2)给它的内容,让我们通过添加分配运算符来扩展您的示例:

class A
{
    int a;
public:
    A(int a) : a(a) { cout << "Constructor a=" << a << endl; }
    ~A()            { cout << "Destructor  a=" << a << endl; }
    void print()    { cout << "Print       a=" << a << endl; }
    A &operator=(const A &other) {
        cout << "Assign operator old=" << a << " a=" << other.a << endl; 
        a = other.a;
    }
};
Run Code Online (Sandbox Code Playgroud)

这将导致:

[vyktor@grepfruit tmp]$ ./a.out 
Constructor a=1
Print       a=1
Constructor a=2
Assign operator old=1 a=2 <- This line explains why destructor is not called
Destructor  a=2
Print       a=2
Destructor  a=2
Run Code Online (Sandbox Code Playgroud)

如果您实施了其中一项:

  • 析构函数- 析构对象的所有成员
  • 复制构造函数- 从复制构造函数参数中的等效成员构造所有对象的成员
  • 复制赋值运算符- 从赋值运算符参数中的等效成员分配所有对象的成员

你应该实施所有这些。这称为三法则