基类类型成员变量通过初始化列表初始化时的构造析构顺序疑问
基类/派生类构造与析构调用次数疑问
问题代码
#include <iostream> using namespace std; class A { public: A() { cout << "A Con" << endl; } virtual ~A() { cout << "A Dec" << endl; } }; class B : A { public: A a; B(A _a) : a(_a) { cout << "B Con" << endl; } virtual ~B() { cout << "B Dec" << endl; } }; int main() { A a; B b(a); }
问题描述
在派生类B中声明了基类A类型的成员变量,运行代码后发现构造函数调用3次,析构函数调用5次。已知第一个构造函数和最后一个析构函数对应main函数中的变量a,但其余调用是怎么回事?为什么析构函数调用次数更多?
个人猜测
A Con -> a in main() A Con -> b in main() (base class constructor) B Con -> b in main() (derived class constructor) A Dec -> temporary value passed in B(A _a) : a(_a), copy constructor is called... B Dec -> b in main() (derived class destructor) A Dec -> member variable in B class (A a;) A Dec -> b in main() (base class destuctor) A Dec -> a in main()
请问我的猜测是否正确?
你的猜测整体是正确的,不过有个细节需要纠正:B构造函数的形参_a不是临时值,它是函数的局部形参,在B构造函数执行完成后会被销毁。我们把整个流程拆解清楚:
完整调用流程(含隐式调用)
构造阶段(你看到的3次打印对应以下标注的打印项)
- 执行
A a;:调用A的无参构造 → 打印A Con - 调用
B b(a)时,先将main中的a拷贝给B构造函数的形参_a:调用A的默认拷贝构造(编译器自动生成,无打印) - 构造B对象的基类部分:调用A的无参构造 → 打印
A Con - 构造B的成员变量
a:用形参_a拷贝初始化,调用A的默认拷贝构造(无打印) - 执行B的构造函数体:打印
B Con
你统计的3次构造调用,应该是指这三个带打印的构造(2次A的无参构造+1次B的构造)。
析构阶段(共5次打印,和你的猜测完全对应)
析构顺序和构造完全相反:
- B构造函数执行完毕,形参
_a被销毁:调用A的析构 → 打印A Dec - main函数执行到末尾,销毁B对象
b:先调用B的析构 → 打印B Dec - 销毁B对象的成员变量
a:调用A的析构 → 打印A Dec - 销毁B对象的基类A部分:调用A的析构 → 打印
A Dec - 销毁main中的
a:调用A的析构 → 打印A Dec
这就是你看到5次析构打印的原因,形参_a的析构是额外的一次,而它对应的拷贝构造因为是编译器生成的默认版本没有打印,所以会出现析构次数看起来比构造打印次数多的情况。
内容的提问来源于stack exchange,提问作者Hashnut
相关产品推荐
相关产品推荐

