C++ 类对象的初始化顺序 ZZ

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

时间: 2024-07-31 04:58:14

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

Java 类中成员初始化顺序

Java 中的类成员 基本分为 静态成员, 实例变量  方法中特别的是静态方法和构造方法. 1.定义一个类 public class ClassLoaderTest { public int a ; public String b; private static int c; public  ClassLoaderTest(){ System.out.println("执行前:"+ a + "  "+ b); a = 10; b = "lisi"

不存在继承关系各类中、不存在对象引用的对象创建初始化顺序

实例3 class One   {        One(String str)      {        System.out.println(str);       }    } class Two   {       One one_1 = new One("one-1");       One one_2 = new One("one-2");       One one_3 = new One("one-3");      Two(S

C#类的成员初始化顺序

首先我们来看看引用类型的成员初始化过程 我们来看一个例子吧 class Program {     static void Main(string[] args)     {         DriveB d = new DriveB();     } } class BaseA {     static DisplayClass a = new DisplayClass("基类静态成员初始化"); DisplayClass BaseA_c = new DisplayClass(&qu

Java 类成员的初始化顺序

Java 类成员的初始化顺序 前言:开发中碰到一个Java文件中有很多的成员变量,包括静态和非静态的,还有很多的初始化方法,很好奇这些成员的初始化顺序,在这里作个研究. ? 1 ?无继承情况下的Java初始化顺序: class Sample { Sample(String s) { System.out.println(s); } Sample() { System.out.println("Sample默认构造函数被调用"); } } class Test { static Samp

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

from: http://blog.csdn.net/classfactory/archive/2004/08/07/68202.aspx 在 C++ 中,同一个翻译单位(.cpp文件)里的全局对象的初始化顺序是先定义的对象先初始化(同时也后析构),但 C++ 标准并没有规定不同翻译单位间全局对象的初始化顺序.按照这个分析,以下的代码可能工作,也可能不工作(cout 是 C++ 用于输出的全局对象,和我们自己的对象位于不同的翻译单位): class A {    A() {        cou

java中对象的初始化顺序

class HelloA { public HelloA() { System.out.println("HelloA"); } { System.out.println("I'm A class"); } static { System.out.println("static A"); }}public class HelloB extends HelloA { public HelloB() { System.out.println(&quo

[Java]变量及其初始化 与 类对象的初始化

1 变量的初始化 1.1 变量的[定义] 1.2 变量的[作用域] 1.3 变量的[初始值] 1.4 补充:缓存变量 1.5 变量的[分类]与[未初始化情况] 2 类对象 2.1 类对象的初始化/构造过程 1 [对象]的初始化流程 2 实验 class Base{ static { System.out.println("[Base:static area]"); }//step1 { System.out.println("Base:instance area")

转:不同编译单元内定义的non-local static 对象的初始化顺序

<Effective C++>条款4中提到了”留意不同编译单元内的non-static变量的初始化顺序“ 下文的描述得很详细,转载过来了. http://blog.csdn.net/chgaowei/article/details/6001433 static对象包括global对象,定义于namespace作用域的对象,在class内的对象,在函数内,以及file作用域内被声明为static的对象. local-static 对象指的是定义在函数内部的对象.其他的被称为non-local-s

11.c#类的成员初始化顺序

转自http://www.cnblogs.com/siceblue/archive/2009/01/15/1376430.html C#作为一种纯面向对象的话言,为它编写的整个代码里面到处都离不开对象.一个对象的完整的生命周期是从开始分配空间到初始化,到使用,最后是销毁,使用的资源被回收.要想真正写出面高质量的代码,我们就得对这期间每一个阶段是怎么样一个状态,framework都做了些什么,我们又能够做些什么都要有些了解才行.   一般来说大部分程序员对于一个创建好了的对象怎么使用都是比较清楚的