C++中多态中构造函数与析构函数的调用
2015-07-15 18:59
489 查看
做个实验,看一下成员变量的构造析构,父类子类的构造析构,以及虚函数对调用的影响。
这段代码的运行输出为:
同学们可以看到,子类的析构没有被执行,怎么让它能值执行呢?把父类的析构修饰为virtual即可:
这样在执行一遍,可以看到结果如果(注释出来的是新增的输出):
小结一下:
通过父类指针指向子类对象实现多态。
多态的时候,父类析构修饰为虚函数,以保证子类析构被调用。
构造顺序是:先父类后子类(这是最主要流程,后两条都再此前提下);初始化列表在构造前执行;构造函数中值调用本类的函数(无论是否为虚函数)。
析构顺序是:先子类后父类(注意虚析构);析构中只调用本类的函数;本类析构后再析构初始化列表中的成员。
#include <iostream> using namespace std; class Member { public: Member(int n):m_n1(n) { cout<<"Member::Member("<<m_n1<<")"<<endl; } ~Member() { cout<<"Member::~Member("<<m_n1<<")"<<endl; } private: const int m_n1; }; class Base { public: Base():m_m1(1) { cout<<"Base::Base()"<<endl; OnConstruct(); } ~Base() //这里目前不是虚函数 { cout<<"Base::~Base()"<<endl; OnDistruct(); } virtual void OnConstruct() { cout<<"Base::OnConstruct()"<<endl; } virtual void OnDistruct() { cout<<"Base::OnDistruct()"<<endl; } virtual void Foo1() { cout<<"Base::Foo1()"<<endl; } void Foo2() { cout<<"Base::Foo2()"<<endl; } private: Member m_m1;//这是个类对象 }; class Drived:public Base { public: Drived():m_m2(2) { cout<<"Drived::Drived()"<<endl; OnConstruct(); } ~Drived() { cout<<"Drived::~Drived()"<<endl; OnDistruct(); } virtual void OnConstruct() { cout<<"Drived::OnConstruct()"<<endl; } virtual void OnDistruct() { cout<<"Drived::OnDistruct()"<<endl; } virtual void Foo1() { cout<<"Drived::Foo1()"<<endl; } void Foo2()//这个不是虚函数 { cout<<"Drived::Foo2()"<<endl; } private: Member m_m2;//这是个类对象 }; int main(int argc, char *argv[]) { Base* p = new Drived; p->Foo1(); p->Foo2(); delete p; return 0; }
这段代码的运行输出为:
Member::Member(1) //父类的初始化列表被执行 Base::Base() //父类构造 Base::OnConstruct()//父类构造中只会调用父类的函数。父类构造完毕 Member::Member(2) //子类构造的初始化列表 Drived::Drived() //子类构造 Drived::OnConstruct()//子类构造中只会调用子类的函数。子类构造完毕 Drived::Foo1()//发生多态,调用子类重写的函数 Base::Foo2() //未多态,调用父类版本的函数 Base::~Base() //父类开始析构 Base::OnDistruct()//父类析构只会调用父类中的函数 Member::~Member(1)//父类成员反初始化
同学们可以看到,子类的析构没有被执行,怎么让它能值执行呢?把父类的析构修饰为virtual即可:
27 ~Base() //这里目前不是虚函数
这样在执行一遍,可以看到结果如果(注释出来的是新增的输出):
Member::Member(1) Base::Base() Base::OnConstruct() Member::Member(2) Drived::Drived() Drived::OnConstruct() Drived::Foo1() Base::Foo2() Drived::~Drived() //子类析构,在父类之前执行 Drived::OnDistruct()//子类析构只会调用子类的函数 Member::~Member(2) //子类成员反初始化 Base::~Base() Base::OnDistruct() Member::~Member(1)
小结一下:
通过父类指针指向子类对象实现多态。
多态的时候,父类析构修饰为虚函数,以保证子类析构被调用。
构造顺序是:先父类后子类(这是最主要流程,后两条都再此前提下);初始化列表在构造前执行;构造函数中值调用本类的函数(无论是否为虚函数)。
析构顺序是:先子类后父类(注意虚析构);析构中只调用本类的函数;本类析构后再析构初始化列表中的成员。
相关文章推荐
- c++三种野指针
- C++学习 C/C++之回调函数
- 黑马程序员-IOS基础之浅谈C语言指针
- c语言程序内存模型
- C/C++程序设计03(宏,const,sizeof,内联函数)
- C++中以固定分隔符分割CString字符串
- c++中的string分割
- C++入门经典 笔记(第二章)程序的组成部分
- 快速傅里叶变化C++实现
- C语言统计输入的单词个数
- C/C++:函数的编译方式与调用约定以及extern “C”的使用
- c++ 中的static
- C语言的struct/union字节对齐
- C++实现数字媒体三维图像渲染
- [C++设计模式] factory 工厂模式
- C/C++内存管理详解
- C语言计算数组的元素和(帮助理解指针)
- c++中,bool与int 的区别
- C/C++ 中头文件相互包含引发的问题
- [转] 国外程序员整理的 C++ 资源大全