堆栈

2013-04-21 111 views
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 2次析构函数调用,并没有与a=1而每个案例都有一个构造函数调用。那么在这种情况下叫做构造器和析构器呢?

+1

你为什么期望使用'a = 1'的析构函数? – juanchopanza 2013-04-21 09:55:50

+2

您是否发现了临时的“A”值?它活不了很长时间。 – 2013-04-21 09:56:55

+0

我现在发现了Kerrek。哇,答案正在涌入。我清楚地知道。感谢大家。 – SolidSun 2013-04-21 10:10:00

回答

2

这是因为你不破坏A(1)你分配A(2)它,让我们来扩展你的例如添加assign 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; } 
    A &operator=(const A &other) { 
     cout << "Assign operator old=" << a << " a=" << other.a << endl; 
     a = other.a; 
    } 
}; 

这将导致到:

[[email protected] 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 

如果您有这些实现的一个:

  • 析构函数 - 自毁对象的所有成员
  • 复制构造 - 建筑对象的所有成员来自复制构造函数参数中的等价成员
  • 复制赋值运算符 - 在赋值运算符的参数

中分配等效成员中的所有对象成员您应该实现所有这些成员。这叫做rule of three

7
a = A(2); 

将使用默认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 

你或许应该阅读有关Rule of three得到更好的理解发生了什么事情。

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

首先构造用于= 1被称为

第二打印被称为

第三其中创建A(2)已被称为它的构造新的对象。

第四这个对象被分配给对象的对象A的这样数据成员= 2

第五的析构函数对象A(2)被称为

第六为对象调用析构函数

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