C++构造函数调用顺序

1.     创建派生类的对象,基类的构造函数优先被调用(也优先于派生类里的成员类);

2.    如果类里面有成员类,成员类的构造函数优先被调用;(也优先于该类本身的构造函数)

3.     基类构造函数如果有多个基类,则构造函数的调用顺序是某类在类派生表中出现的顺序而不是它们在成员初始化表中的顺序;

4.     成员类对象构造函数如果有多个成员类对象,则构造函数的调用顺序是对象在类中被声明的顺序而不是它们出现在成员初始化表中的顺序;

5.     派生类构造函数,作为一般规则派生类构造函数应该不能直接向一个基类数据成员赋值而是把值传递给适当的基类构造函数,否则两个类的实现变成紧耦合的(tightly coupled)将更加难于正确地修改或扩展基类的实现。(基类设计者的责任是提供一组适当的基类构造函数)

综上可以得出,初始化顺序:

父类构造函数–>成员类对象构造函数–>自身构造函数

其中成员变量的初始化与声明顺序有关,构造函数的调用顺序是类派生列表中的顺序。
析构顺序和构造顺序相反

下面是最近笔试的某网络公司的题目:

#include <iostream>
using namespace std;

class A
{
      public:
            A(){ cout<<“A”<<endl;}
            virtual ~A(){ cout<<“~A”<<endl; }
};

class B: public A
{
      public:
             B(){ cout<<“B”<<endl;}
             ~B() {cout<<“~B”<<endl; }
      private:
              A a;
};

class C: public A, public B     //类在派生表中的继承列表
{
      public:
              C() {cout<<“C”<<endl;}
              ~C() {cout<<“~C”<<endl; }
      private:
              B b;
      public:
             A a;
};

int main()
{
    C * p = new C;
    delete p;
   
    system(“PAUSE”);
    return 0;
}

结果和分析:

A          //1 父类A的构造函数
A         //2 父类B中A的构造函数
A         //3 父类B中成员变量b初始化 (调用父类A的构造函数)
B         //4  父类B中成员变量b初始化 (调用父类B的构造函数)
A        //5   C中成员变量b 的构造
A
B
A         //6 C中成员变量a的构造
C         //7 C的构造函数最后调用 (finally ,-__-|||)
~C
~A
~B
~A
~A
~B
~A
~A
~A

====================================

综上可以看出,1~4 按照在派生表中的出现次序进行初始化,首先调用父类的构造函数

5, 6 调用 成员变量的构造函数

7 调用自身的构造函数

PS:更复杂的情况,可以试下虚继承。

在有虚继承和一般继承存在的情况下,优先虚继承

例如class C: public B, virtual public A

则先调用A的构造函数,再调用B的构造函数

=================================================================================================================================

http://sun.solrex.org/?p=254

C++ 类对象的初始化顺序 ZZ的更多相关文章

  1. java类对象的初始化顺序

    在下面这个例子中,我们分别在父类和子类中测试了静态代码块.普通代码块.静态成员变量.普通成员变量.构造器.静态内部类. 一:代码块及变量测试 class Field{ public static St ...

  2. [C#解惑] #2 对象的初始化顺序

    谜题 在上一篇C#解惑中,我们提到了对象的初始化顺序.当我们创建一个子类的实例时,总是会先执行基类的构造函数,然后再执行子类的构造函数.那么实例字段是什么时候初始化的呢?静态构造函数和静态字段呢?今天 ...

  3. java类的成员初始化顺序和初始化块知识

    java类的成员初始化顺序和初始化块知识 转自:http://blog.csdn.net/lgfeng218/article/details/7606735 属性.方法.构造方法和自由块都是类中的成员 ...

  4. [百度空间] [转] 在 Visual C++ 中控制全局对象的初始化顺序

    from: http://blog.csdn.net/classfactory/archive/2004/08/07/68202.aspx 在 C++ 中,同一个翻译单位(.cpp文件)里的全局对象的 ...

  5. Java 类成员的初始化顺序

    Java 类成员的初始化顺序 前言:开发中碰到一个Java文件中有很多的成员变量,包括静态和非静态的,还有很多的初始化方法,很好奇这些成员的初始化顺序,在这里作个研究.   1  无继承情况下的Jav ...

  6. Java类的成员初始化顺序

    Java类的成员初始化顺序 2017-06-01 代码: public class InitializeSequence { public static void main(String[] args ...

  7. Java对象的初始化顺序

    new一个对象时,该对象的初始化顺序如下 : 父类中的静态成员变量 父类中的静态代码块 子类中的静态成员变量 子类中的静态代码块 父类中的非静态变量 父类中的非静态代码块 父类构造函数 子类中的非静态 ...

  8. java中的多构造函数以及类字段的初始化顺序

    1.同一个类可以有多个构造函数,多个构造函数之间通过参数来区分.这是方法重载的一个实例.构造函数之间可以相互调用. 2.类的初始化块:可以在类中使用“{”和“}”将语句包围起来,直接将其作为类的成员. ...

  9. C#类的成员初始化顺序

    首先我们来看看引用类型的成员初始化过程 我们来看一个例子吧 class Program {     static void Main(string[] args)     {         Driv ...

随机推荐

  1. Java - 自定义异常(尚学堂第六章异常机制作业计算平均数)

    编写一个计算N个学生分数平均分的程序.程序应该提示用户输入N的值,如何必须输入所有N个学生分数.如果用户输入的分数是一个负数,则应该抛出一个异常并捕获,提示“分数必须是正数或者0”.并提示用户再次输入 ...

  2. 80x25彩色字符模式

    80x25彩色字符模式下显示缓冲区的结构: 在内存地址空间中,B8000H~BFFFFH共32KB的空间,为80x25彩色字符模式的显示缓冲区.往这个地址空间中写入数据,写入的内容会立即出现在显示器上 ...

  3. CentOS6.5安装testlink1.9.14

    前提条件:准备一台CentOS6.5虚拟机,配置好IP,关闭iptables和selinux. 这里提供上我的云盘软件,可以去这里下载:http://pan.baidu.com/s/1qXymele ...

  4. linux下定时任务的工具crontab的用法

    Linux计划任务工具cron用法详解 linux下大名鼎鼎的计划任务工具crontab的使用介绍baidu.google上多得让人眼花缭乱,本着“天下文章一大抄”的觉悟,加上本人日常工作中总结的使用 ...

  5. ssh 端口转发实现外网 80 端口映射到内网 80 端口

    开发中经常需要外网服务映射到本机内网服务的需要,便于调试. 以前都是同事帮着配,这两天自己也看了一下 ssh 端口转发. 同事分分钟钟搞定的事情,自己折腾了 2 天, 真是弱爆了. 最初老想不明白一件 ...

  6. unity鼠标拖动物体旋转

    using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> / ...

  7. Ubuntu16.04 静态IP配置

    Ubuntu16.04 静态IP配置 修改配置 登录系统后,编辑文件/etc/network/interfaces.原始的内容如下: # This file describes the network ...

  8. ubuntu 修改 ls 下的目录颜色

    ubuntu 下, ls 显示的目录的颜色,怎么说呢,看起来太费劲了. 于是想着修改成容易识别的颜色. 于是搜索了一下. 这里列举三个搜到的教程吧. 简单说我按这上面的方法做了,然后都失败了. 1.  ...

  9. ES6内容

    iterator 遍历器iterator makeIterator是个遍历器,生成遍历器对象it var it = makeIterator(['a', 'b']); it.next() // { v ...

  10. 快手、抖音、微视类短视频SDK接入教程,7步就能搞定

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由视频咖 发表于云+社区专栏 终端部分 按照如下三步操作,可以用 XCode 或者 Android Studio 编译和调试小视频 Ap ...