构造函数/析构函数在堆栈上的调用顺序
Constructor/Destructor call order on stack
我有以下简单的代码:
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
没有,而每种情况都有一个构造函数调用。那么在这种情况下如何调用构造函数和析构函数呢?
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
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
}
这是因为您没有破坏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 -销毁对象的所有成员
- 复制构造函数 -从复制构造函数形参 中的等效成员构造对象的所有成员
- 复制赋值操作符—从赋值操作符形参 中的等效成员中赋值对象的所有成员
你应该实现所有这些。
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)
}
首先,a=1的构造函数称为
第二个打印字叫做
第三,您创建的新对象A(2)调用了它的构造函数。
第四,这个对象被赋值给对象a,所以对象a的数据成员=2
第五,对象A(2)的析构函数称为 第六,对象a的析构函数称为相关文章:
- 以 f() + g() 调用顺序的 C++ 函数
- 如何创建跟踪以显示存在递归的调用顺序
- 析构函数的奇怪调用顺序
- 输入法管理器函数 - 平假名到汉字候选列表 c++ covnersion 的正确调用顺序
- 构造函数的调用顺序
- 模板func和非模板func调用顺序
- C++对返回*this的成员函数的重复调用顺序
- 在C++中,析构函数的调用顺序和成员变量的销毁顺序是什么
- XSetWMProtocols 和 glXCreateContext 在多线程环境中调用顺序
- __attribute__((构造函数)) 调用顺序混淆
- 此代码是否依赖于函数调用顺序未定义的行为
- 如何强制实施析构函数的调用顺序
- C++在递归函数中平衡了树/调用顺序
- 构造调用顺序(C++)
- 无法理解析构函数调用顺序
- 构造函数调用顺序与组合
- 构造函数/析构函数在堆栈上的调用顺序
- 递归到迭代,保留变量和调用顺序
- Qt队列连接中的插槽调用顺序
- visual studio-C++函数调用顺序(boost)-混乱