构造函数

   先看看构造函数的调用顺序规则,只要我们在平时编程的时候遵守这种约定,任何关于构造函数的调用问题都能解决;构造函数的调用顺序总是如下:
1.基类构造函数。如果有多个基类,则构造函数的调用顺序是某类在类派生表中出现的顺序,而不是它们在成员初始化表中的顺序。
2.成员类对象构造函数。如果有多个成员类对象则构造函数的调用顺序是对象在类中被声明的顺序,而不是它们出现在成员初始化表中的顺序。
3.派生类构造函数。

析构函数
    析构函数的调用顺序与构造函数的调用顺序正好相反,将上面3个点反过来用就可以了,首先调用派生类的析构函数;其次再调用成员类对象的析构函数;最后调用基类的析构函数。
    析构函数在下边3种情况时被调用:
    1.对象生命周期结束,被销毁时(一般类成员的指针变量与引用都i不自动调用析构函数);
    2.delete指向对象的指针时,或delete指向对象的基类类型指针,而其基类虚构函数是虚函数时;
    3.对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。

virtual析构函数
下面来说一说为多态基类声明virtual析构函数:
在C++中,构造函数不能声时为虚函数,这是因为编译器在构造对象时,必须知道确切类型,才能正确的生成对象,因此,不允许使用动态束定;其次,在构造函数执行之前,对象并不存在,无法使用指向此此对象的指针来调用构造函数,然而,析构函数是可以声明为虚函数;C++明白指出,当derived class对象经由一个base class指针被删除,而该base class带着一个non-virtual析构函数,其结果未有定义---实际执行时通常发生的是对象的derived成分没被销毁掉。

class Derive:public Base
{
public:
    Derive(){ std::cout<<"Derive::Derive()"<<std::endl; }
    ~Derive(){ std::cout<<"Derive::~Derive()"<<std::endl; }
};

int _tmain(int argc, _TCHAR* argv[])
{
    Base* pBase = new Derive();
    delete pBase;

return 0;
}

输出结果是:
Base::Base()
Derive::Derive()
Derive::~Derive()
Base::~Base()

由结果可以看出,在父类的虚析构函数有自己的实现时,当调用完子类对象的析构函数结束后,还会调用父类的析构函数。而一般的虚函数都是子类覆盖了父类的,调用完子类方法后不会再调用父类的方法。况且虚析构函数也不能想一般的虚函数一样写成纯虚函数的形式。这一切还是由于析构函数的特殊性决定的。

构造和析构函数都有着特别的意义,这是与其它函数不同的,并且在一个类层次中析构函数都会被调用,并且调用顺序是有规定的(文章开头已讲),这些是编译器决定的。因此我们必须给出虚析构函数的函数体以供调用。既然调用顺序已定,父类对象的析构函数总是会被调用,所以就没有被子类覆盖之说了。

C++构造函数和析构函数顺序的更多相关文章

  1. C++C++中构造函数与析构函数的调用顺序

    http://blog.csdn.net/xw13106209/article/details/6899370 1.参考文献 参考1: C++继承中构造函数.析构函数调用顺序及虚函数的动态绑定 参考2 ...

  2. C++-理解构造函数、析构函数执行顺序

    先初始化序列中的函数调用,如果基类构造函数为非引用传递,则引起参数的拷贝构造 再: 先类内的成员构造函数(拷贝/默认),再类的构造函数:先基类,再派生类: 本文主要说明对象创建时构造函数的执行顺序,对 ...

  3. C++ 构造函数和析构函数的调用顺序、虚析构函数的作用

    构造函数和析构函数的调用顺序 构造函数的调用顺序: 当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达最底层的目标派生类的构造函数为止. 析构函数的调用书序: ...

  4. C++构造函数和析构函数的调用顺序

    1.构造函数的调用顺序 基类构造函数.对象成员构造函数.派生类本身的构造函数 2.析构函数的调用顺序 派生类本身的析构函数.对象成员析构函数.基类析构函数(与构造顺序正好相反) 3.特例 局部对象,在 ...

  5. C++中构造函数和析构函数的调用顺序

    一般而言,析构函数调用的顺序和构造函数调用顺序相反,但是,对象的存储类别可以改变调用析构函数的顺序.举例说明: CreateAndDestroy类的定义 CreateAndDestroy类的成员函数的 ...

  6. C++:派生类的构造函数和析构函数的调用顺序

    一.派生类 在C++编程中,我们在编写一个基类的派生类时,大致可以分为四步: • 吸收基类的成员:不论是数据成员还是函数成员,派生类吸收除基类的构造函数和析构函数之外的全部成员. • 改造基类函数:在 ...

  7. C++学习笔记(7)----类的数组中构造函数和析构函数的调用顺序

    C++类的数组中构造函数和析构函数的调用顺序(2) 对于如下的代码: #include<iostream> using namespace std; class CBase { priva ...

  8. C++学习笔记(6)----基类和派生类的构造函数和析构函数的执行顺序

    基类和派生类:构造函数和析构函数的执行顺序 在Visual Studio中,新建控制台工程,构造类如下: #include<iostream> using namespace std; c ...

  9. c++学习笔记4,派生类的构造函数与析构函数的调用顺序(一)

    測试源代码: //測试派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include <iostream> using namespace ...

随机推荐

  1. [shell] 循环判断输入值

    做个记录 until [[ $flag == "yes" || $flag == "exit" ]] do read -p "请确认统一/合服前后数据 ...

  2. C++ map 遍历

    #include <iostream> #include <map> using namespace std; int main(){ map<int,int> m ...

  3. SGU 126 Boxes(模拟题|二进制)

    Translate:Sgu/126 126. 盒子 time limit per test: 0.5 sec. memory limit per test: 4096 KB 有两个盒子. 第一个盒子里 ...

  4. vim 末行模式简单练习

    练习 1 . 复制/etc/grub2.cfg文件至/tmp目录中,用查找替换命令删除/tmp/grub2.cfg文件中以空白字符开头的行的行首的空白字符 :%s#^[[:space:]]\+##g ...

  5. QMdiArea及QMdiSubWindow实现父子窗口及布局方法

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QMdiArea及QMdiSubWindow实现父子窗口及布局方法     本文地址:http ...

  6. 设计模式PHP篇(二)————工厂模式

    一个很简单的工厂模式.代码如下: <?php interface Person { public function sex(); } class Man implements Person { ...

  7. 利用Docker安装Web前端性能测试工具Sitespeed.io

    目录结构 一.Sitespeed.io概述 1.Sitespeed.io简介 2.Sitespeed.io使用场景 二.Sitespeed.io的安装和使用 1.安装Sitespeed.io 2.连接 ...

  8. C# 事件总线 EventBus

    1. 引言 事件总线这个概念对你来说可能很陌生,但提到观察者(发布-订阅)模式,你也许就很熟悉.事件总线是对发布-订阅模式的一种实现.它是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需 ...

  9. Linux服务器ping不通域名出现的unknown host 错误解决办法

    "ping: unknown host www.baidu.com" 解决方法 如果某台Linux服务器ping不通域名, 如下提示: # ping www.baidu.compi ...

  10. 在64位系统上部署BDE的要点

    首先,据我所知,Borland/CodeGear没有发布过支持64bit windows的BDE安装包,如果你在网上看到了相关的BDE安装包,很有可能是使用者自己重新打包发布的. 无论是在32bit  ...