总结笔记-c++成员变量、构造函数以及析构函数的执行顺序
来源:互联网 发布:淘宝申请介入流程 编辑:程序博客网 时间:2024/06/06 02:44
在我的之前的博客http://blog.csdn.net/caoyan_12727/article/details/52356844有提到c++各种变量的初始化规则,本文将总结c++中涉及到的各种变量的初始化顺序和析构函
以及构造函数初始化的顺序!!
第一步:类的静态成员变量
#include <stdlib.h>#include <sys/types.h>#include <assert.h>#include <iostream>#include<memory>using namespace std;class a{public:int a1;int a2;static int a3;a(int x) :a1(x){a2 = 2;a3 = 7;}};//int a::a3 = 4;int main(){a aa(2);cout << a::a3 << endl;return 0;}我们把int a::a3这一行注释掉,vs2103编译器提示错误:
直接显示未定义的外部变量,说明在类中的static int a3语句连定义都算不上,一定要在类外进行定义!!!
第二步:全局变量和类中静态变量的执行顺序:
测试程序:
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <assert.h>#include <iostream>#include<memory>#include <iostream>#include <string>using namespace std;struct B{B(){ std::cout << "b\n"; }};struct C{C(){ std::cout << "c\n"; }};struct D{D(){ std::cout << "d\n"; }};struct E{E(){ std::cout << "e\n"; }};struct F{F(){ std::cout << "f\n"; }};struct A{static B b;D d;C c;A() :d(), c(){}};struct AA :A{static E e;};F f;B A::b;E AA::e;int main(){A a;return 0;}测试结果:
替换顺序:
B A::b;F f;E AA::e;
测试结果:
可以看到,在全局变量、父类静态变量子类静态变量同时存在的情况下,初始化规则是按照它们定义的先后顺序进行的,同时在类中,比如在类A中,成员c和成员d的初始化顺序和它们的定义顺序是一样的,即先初始化成员d,然后初始化成员c!!!因为类的静态成员同样被存储在.data段,它们可以看做是带有“特殊作用域的全局变量”。
第三步:基类和虚基类的析构函数和构造函数的调用顺序
测试代码:
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <assert.h>#include <iostream>#include<memory>using namespace std;class a{public:int a1;int a2;a(int x) :a1(x){cout << "construct class a!" << endl;}~a(){cout << "discontruct class a!" << endl;}};class b{public:int b1;int b2;b(int x) :b1(x){cout << "construct class b!" << endl;}~b(){cout << "discontruct class b!" << endl;}};class d{public:int d1;int d2;d(){cout << "construct class d!" << endl;}~d(){cout << "distconruct class d!" << endl;}};class e{public:int e1;int e2;e(){cout << "construct class e!" << endl;}~e(){cout << "discontruct class e!" << endl;}};class c :virtual public d, public b, public a, virtual public e{public:int c1;int c2;c(int x, int y, int z) :a(y), b(z), c1(x){cout << "construct clsss c! " << endl;}~c(){cout << "discontruct class c!" << endl;}};int con(){c two(1, 2, 3);return 0;}int main(){con();return 0;}测试输出:
修改继承顺序:
class c :virtual public e, public a, public b, virtual public d{public:int c1;int c2;c(int x, int y, int z) :a(y), b(z), c1(x){cout << "construct clsss c! " << endl;}~c(){cout << "discontruct class c!" << endl;}};输出结果:
在例子中类c虚拟继承类d和类e,普通继承类a和类吧,从构造函数可以看出,在同一层次的继承中,虚拟继承的构造函数要先于非虚拟继承的构造函数,在同一层的所有非虚拟继承的类中,其构造函数的执行顺序是先左后右,同样的在同一层所有非虚拟继承的类中,构造函数的执行也是先左后右,和类的定义顺序无关!!无关!!
struct B{public:int b1;int b2;B(int x,int y):b1(x),b2(y){cout << "b" << endl;}};struct D{public:D(){cout << "d" << endl;}};struct C{public:D d;B b;<strong><span style="color:#ff0000;">C():b(1,2){ std::cout << "c\n"; }</span></strong>};int main(){C c;return 0;}输出结果:
第四步:函数中的局部静态变量初始化
struct B{int b1 = 1;B(){ std::cout << "b\n"; }};struct C{int c1 = 2;C(){ std::cout << "c\n"; }};struct D{int d1 = 3;D(){ std::cout << "d\n"; }};struct E{int e1 = 4;E(){ std::cout << "e\n"; }};struct F{int f1 = 5;F(){ std::cout << "f\n"; }};void func(){static D d;}B b;C c;static F f;int main(){E e;func();return 0;}测试结果:
所以总结一下c++的变量初始化顺序:
(1)先初始化全局变量和全局静态变量(不管是不是类里面的静态变量,因为此时类中的静态变量会被当做全局变量看待),如果有局部静态变量,则在局部函数被调用时,它里面的局部静态变量才会初始化;不管是基类中的静态变量还是派生类中的静态变量,它们都存储在.data段,会被当做全局变量来看待,所以它的初始化和它们的定义顺序一致!!!
(2)在成员初始化列表中,成员初始化的顺序和定义的顺序一致,和在初始化列表里出现的顺序无关;
- 总结笔记-c++成员变量、构造函数以及析构函数的执行顺序
- 关于构造函数析构函数以及成员变量内存分配顺序的一些问题
- 成员变量和构造函数执行顺序
- 成员变量和构造函数执行顺序
- 子类、父类、静态成员变量,构造函数的执行顺序
- [C#]父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- [C#]父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- [C++]父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- 关于类继承/初始化成员变量/构造函数/析构函数 执行顺序
- 关于类继承/初始化成员变量/构造函数/析构函数 执行顺序
- 关于类继承/初始化成员变量/构造函数/析构函数 执行顺序
- 构造函数初始化、static代码块初始化、成员变量初始化、以及在子父类中混合的执行顺序实例
- java中成员变量、代码块、构造函数执行顺序
- (静态)初始化块、成员变量、构造函数执行顺序
- Java静态变量 静态代码块 主函数 成员变量 构造代码块 构造函数的执行顺序
- C++的静态成员函数,成员变量,构造函数,析构函数,拷贝构造函数
- 【C/C++学院】0819-/类的成员函数与const-mutable /构造与析构/拷贝构造deletedefault以及深浅拷贝/静态成员函数成员变量类在内存的存储默认参数/友元类以及友元函数
- C#类成员变量初始化与构造函数执行的顺序
- SDWebImage的原理
- 算法(伪代码)的书写
- 我的学习方法
- 【搬自CC_GERALD07】【JZ雅礼联考】Ztxz16学图论 题解
- Python实现dict转换成HTML表格
- 总结笔记-c++成员变量、构造函数以及析构函数的执行顺序
- MySQL 日期默认值的问题
- USACO 1.1.2 - Greedy Gift Givers(模拟)
- 【题&结论(递归标连通块)】【搜索(IDA*)】NKOJ 2440 数字消除游戏
- 基础知识
- sqlserver 审核
- Netty 处理简单HTTP请求的例子
- 字符串+哈希表+小动态规划(Longest Substring Without Repeating Characters -- LeetCode)
- 深入理解Activity 生命周期