C++构造函数和析构函数的调用顺序
1、构造函数的调用顺序
基类构造函数、对象成员构造函数、派生类本身的构造函数
2、析构函数的调用顺序
派生类本身的析构函数、对象成员析构函数、基类析构函数(与构造顺序正好相反)
3、特例
局部对象,在退出程序块时析构
静态对象,在定义所在文件结束时析构
全局对象,在程序结束时析构
继承对象,先析构派生类,再析构父类
对象成员,先析构类对象,再析构对象成员
4、例子
#include <iostream>
using namespace std; class Base1
{
public:
Base1(void){cnt++;cout<<"Base1::constructor("<<cnt<<")"<<endl;}
~Base1(void){cnt--;cout<<"Base1::deconstructor("<<cnt + <<")"<<endl;}
private:
static int cnt;
};
int Base1::cnt = ; class Base2
{
public:
Base2(int m){num = m; cout<<"Base2::constructor("<<num<<")"<<endl;}
~Base2(void){cout<<"Base2::deconstructor("<<num<<")"<<endl;}
private:
int num;
}; class Example
{
public:
Example(int n){num = n; cout<<"Example::constructor("<<num<<")"<<endl;}
~Example(void){cout<<"Example::deconstructor("<<num<<")"<<endl;}
private:
int num;
}; class Derived:public Base1, public Base2
{
public:
Derived(int m, int n):Base2(m),ex(n){cnt++;cout<<"Derived::constructor("<<cnt<<")"<<endl;}
~Derived(void){cnt--;cout<<"Derived::deconstructor("<<cnt+<<")"<<endl;}
private:
Example ex;
static Example stex; //Example::constructor(1) //不能输出
static int cnt;
};
int Derived::cnt = ; Derived ge_a(,); // Base1::constructor(1)
// Base2::constructor(1)
// Example::constructor(2)
// Derived::constructor(1)
static Derived gs_b(,); // Base1::constructor(2)
// Base2::constructor(3)
// Example::constructor(4)
// Derived::constructor(2)
int main(void)
{
cout << "---------start---------" << endl;
Derived d(,); // Base1::constructor(3)
// Base2::constructor(5)
// Example::constructor(6)
// Derived::constructor(3)
Derived e(,); // Base1::constructor(4)
// Base2::constructor(7)
// Example::constructor(8)
// Derived::constructor(4)
cout << "----------end----------" << endl; //Derived e(7,8) 析构
// Derived::deconstructor(4)
// Example::deconstructor(8)
// Base2::deconstructor(7)
// Base1::deconstructor(4) //Derived d(5,6) 析构
// Derived::deconstructor(3)
// Example::deconstructor(6)
// Base2::deconstructor(5)
// Base1::deconstructor(3)
return ;
}
//static Derived gs_b(3,4) 析构
// Derived::deconstructor(2)
// Example::deconstructor(4)
// Base2::deconstructor(3)
// Base1::deconstructor(2)
//Derived ge_a(1,2) 析构
// Derived::deconstructor(1)
// Example::deconstructor(2)
// Base2::deconstructor(1)
// Base1::deconstructor(1) //static Example stex 析构
//Example::deconstructor(1) //不能输出
#include <iostream>
using namespace std;
class A
{
public:
A(){cout<<"A::constructor"<<endl;};
~A(){cout<<"A::deconstructor"<<endl;};
};
class B
{
public:
B(){cout<<"B::constructor"<<endl;};
~B(){cout<<"B::deconstructor"<<endl;};
};
class C : public A
{
public:
C(){cout<<"C::constructor"<<endl;};
~C(){cout<<"C::deconstructor"<<endl;};
private:
// static B b;
B b;
};
class D : public C
{
public:
D(){cout<<"D::constructor"<<endl;};
~D(){cout<<"D::deconstructor"<<endl;};
}; int main(void)
{
C* pd = new D();
delete pd;
return ;
}
/* Output
----->B b
A::constructor
B::constructor
C::constructor
D::constructor
C::deconstructor
B::deconstructor
A::deconstructor ----->static B b
A::constructor
C::constructor
D::constructor
C::deconstructor
A::deconstructor
*/
C++构造函数和析构函数的调用顺序的更多相关文章
- C++C++中构造函数与析构函数的调用顺序
http://blog.csdn.net/xw13106209/article/details/6899370 1.参考文献 参考1: C++继承中构造函数.析构函数调用顺序及虚函数的动态绑定 参考2 ...
- C++ 构造函数和析构函数的调用顺序、虚析构函数的作用
构造函数和析构函数的调用顺序 构造函数的调用顺序: 当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达最底层的目标派生类的构造函数为止. 析构函数的调用书序: ...
- C++中构造函数和析构函数的调用顺序
一般而言,析构函数调用的顺序和构造函数调用顺序相反,但是,对象的存储类别可以改变调用析构函数的顺序.举例说明: CreateAndDestroy类的定义 CreateAndDestroy类的成员函数的 ...
- C++学习笔记(7)----类的数组中构造函数和析构函数的调用顺序
C++类的数组中构造函数和析构函数的调用顺序(2) 对于如下的代码: #include<iostream> using namespace std; class CBase { priva ...
- C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题
#include <iostream> using namespace std; class A{ int data_a; public: A(){ data_a = ; cout < ...
- C++:派生类的构造函数和析构函数的调用顺序
一.派生类 在C++编程中,我们在编写一个基类的派生类时,大致可以分为四步: • 吸收基类的成员:不论是数据成员还是函数成员,派生类吸收除基类的构造函数和析构函数之外的全部成员. • 改造基类函数:在 ...
- c++学习笔记4,派生类的构造函数与析构函数的调用顺序(一)
測试源代码: //測试派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include <iostream> using namespace ...
- 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数
1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...
- C++学习笔记(6)----基类和派生类的构造函数和析构函数的执行顺序
基类和派生类:构造函数和析构函数的执行顺序 在Visual Studio中,新建控制台工程,构造类如下: #include<iostream> using namespace std; c ...
随机推荐
- SDOI 2019 R1 摸鱼记
Day -1 学文化课第一天,也是这周最后一天. 昨晚 mxl 让我们今天下午放学走,大概六点的样子,感觉良好. 早读班主任送来请假条,跟我讲中午放学走??? 很懵逼,以为班主任口胡了,问了一句&qu ...
- JAVA之锁-cas
CAS是什么? CAS是英文单词CompareAndSwap的缩写,中文意思是:比较并替换.CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B. CAS指令执行时,当且仅当内存地址 ...
- [Deep Learning] 常用的Active functions & Optimizers
深度学习的基本原理是基于人工神经网络,输入信号经过非线性的active function,传入到下一层神经元:再经过下一层神经元的activate,继续往下传递,如此循环往复,直到输出层.正是因为这些 ...
- JS中JSON和string字符串相互转换
在Firefox,chrome,opera,safari,ie9,ie8等高级浏览器直接可以用JSON对象的stringify()和parse()方法. JSON.stringify(obj)将JSO ...
- 挖矿病毒、ddos入侵流程及溯源
一 挖矿病毒简介 攻击者利用相关安全隐患向目标机器种植病毒的行为. 二 攻击方式 攻击者通常利用弱口令.未授权.代码执行.命令执行等漏洞进行传播.示例如下: 示例1: POST /tmUnblo ...
- L1-Day10
1.你需要的是更多的练习.[我的翻译]That you need is more practice.[标准答案]What you need is more practice[对比分析]主语从句用Tha ...
- PHP笔记:单引号与双引号区别
PHP笔记:单引号与双引号区别 php中使用字符串时,可以使用单引号或者双引号,这里总结一下二者的不同: 一.解析字符内容 双引号中的变量会会经过编译器解析 单引号中的变量不会被解析 如下: < ...
- docker方式mysql设置字符集
在docker上部署mysql时,mysql的默认字符集是latin1,这样如果日后有中文会出现异常,不能存储等,因为latin1是不支持中文的. 所以需要将字符集调整为utf8. 方法: 首先启动m ...
- Linux-ubuntu16.04安装 mysql5.7-PHP7.0+Swoole
步骤1 – 安装MySQL 在 Ubuntu 16.04 中,默认情况下,只有最新版本的 MySQL 包含在 APT 软件包存储库中.只需更新服务器上的包索引并安装默认包 apt-get. sudo ...
- 基于WebGL/Threejs技术的BIM模型轻量化之图元合并
伴随着互联网的发展,从桌面端走向Web端.移动端必然的趋势.互联网技术的兴起极大地改变了我们的娱乐.生活和生产方式.尤其是HTML5/WebGL技术的发展更是在各个行业内引起颠覆性的变化.随着WebG ...