5

我有以下简单的代码:

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;
}

输出是:

Constructor a=1
Print       a=1
Constructor a=2
Destructor  a=2
Print       a=2
Destructor  a=2

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

4

5 回答 5

7
a = A(2);

将使用 defaultoperator=为 分配新值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

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

于 2013-04-21T09:55:26.987 回答
4
void f()
{
    A a(1);
      //  Constructor a=1
    a.print();
      //  Print       a=1
    a = A(2);
      // Constructor a=2
      // also operator=
      // Destructor  a=2
    a.print();
      // Print       a=2
      // Destructor  a=2
}
于 2013-04-21T09:56:23.100 回答
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;
    }
};

这将导致:

[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

如果您实施了其中之一:

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

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

于 2013-04-21T10:02:55.757 回答
2
void f()
{
    A a(1); // Constructor a=1 (a.a(1) is called)
    a.print(); // Print a=1
    a = A(2); // Constructor a=2 (Temporary unnamed object A(2) is constructed)
              // compiler generated a.operator=(const A&); is called and then
              // Destructor  a=2 (Temporary unnamed object is destroyed.
    a.print(); // Print a=2
              // Destructor  a=2 (a.~a() is called)
}
于 2013-04-21T10:03:42.167 回答
1

首先调用 a=1 的构造函数

其次打印被称为

第三,您创建的新对象 A(2) 调用了它的构造函数。

第四把这个对象赋值给对象a所以对象a的数据成员=2

第五,对象 A(2) 的析构函数被调用

第六,对象 a 的析构函数被调用

于 2013-04-21T10:01:54.840 回答