精华内容
下载资源
问答
  • 构造函数执行顺序

    千次阅读 2018-11-17 19:32:18
    通过示例说明: #include class Base ...但是,如果是在Base的构造函数中调用,因为此时Devied还没构造,对象还不是Devied类型,所以调用的是Base::f(),这个查看构造函数中的函数调用可以看出。

    通过示例说明:

    #include <iostream>
    
    class Base
    {
    public:
        Base();
        virtual void f();
        virtual void func();
    };
    
    Base::Base()
    {
        std::cout << "Base construct" << std::endl;
        f();
    }
    
    void Base::func()
    {
        f();
    }
    void Base::f()
    {
        std::cout << "Base f() called" << std::endl;
    }
    
    class Devied : public Base
    {
    public:
        Devied();
        void f();
    };
    
    Devied::Devied()
    {
        std::cout << "Devied construct" << std::endl;
    }
    
    void Devied::f()
    {
        std::cout << "Devied f() called" << std::endl;
    }
    
    //by zhaocl
    int main()
    {
        Devied d;
        d.func();
        system( "pause" );
        return 0;
    }

    运行结果:

    Base construct
    Base f() called
    Devied construct
    Devied f() called

    基础知识点总结:

    1、构造函数先父类再子类,所以先 Base 再 Decied

    2、Base 中调用 f() ,该函数是一个虚函数,所以一般会调用 Devied::f(),因为对象d是Devied类型的,查看Base::Func() 中的函数调用可以得出结果。但是,如果是在Base的构造函数中调用,因为此时Devied还没构造,对象还不是Devied类型,所以调用的是Base::f(),这个查看构造函数中的函数调用可以看出。

    展开全文
  •  3 构造函数,(创建对象时执行完2后再执行构造函数,不管构造函数是public还是private) */ public class Test{ public Test(){ System.out.println("类Test构造方法被执行 6"); } { System.out.println("类...
  • Java 静态块、构造块、构造函数执行顺序

    请先参照这两个帖子:
    http://blog.csdn.net/kingzone_2008/article/details/45015301
    http://bbs.csdn.net/topics/391001417%20%22%22
    静态块:用static申明,JVM加载类时执行,仅执行一次
    构造块:类中直接用{}定义,每一次创建对象时执行
    执行顺序优先级:静态块>main()>构造块>构造方法
    静态块和静态属性优先执行,谁在前就先执行谁
    注意:
    1、每调用一次构造方法,则执行一次构造块
    2、静态块只在类加载的时候加载一次
    3、有多个静态变量或块时,按声明顺序加载

    public class Practice {  
        public static void main(String[] args) {  
            new Father();  
            new Son();  
        }  
    }  
    class Father {  
        protected int n = 5;  
        protected static int m = 5;
        public static Father p = new Father();
        public static Father p1 = new Father();
    
        {//构造块  
            n = n * 2;  
            m = m * 2;  
            System.out.print("父类**构造块**调用;");
            System.out.print("n="+n);  
            System.out.println("  m="+m);  
        }  
    
        static {//实例化多个对象时,静态块只执行一次,即在第一个实例化对象时执行
            m = m * 2;  
            System.out.println("父类%%静态块%%调用; m="+m);  
        }  
    
    
        public Father() {  //父类构造函数
            this.n = n * 10;  
            m = m + 10;  
            System.out.print("父类$$构造函数$$;   n="+n);  
            System.out.println("    m="+m);  
        }  
    }  
    
    class Son extends Father {  
        private int sn=3;  
        private static int sm=3;  
        static {  
            m = m + 2;  
            sm=sm+2;  
            System.out.println("【 子类 】@@ 静态块 @@调用;    m="+m);  
        }  
        {  
            n = n + 2;  
            sn=sn+2;  
            m = m + 2;  
            System.out.println("【 子类 】^^ 构造块 ^^调用;");  
            System.out.println("n="+n);  
            System.out.println("sn="+sn);  
            System.out.println("m="+m);  
        }  
    
        public Son() {  
            this.n = n + 10;  
            sn=sn+10;  
            m = m + 10;  
            System.out.println("【 子 类 】[[ 构造函数 ]];\nn="+n);  
            System.out.println("m="+m);  
        }  
    }   

    结果:(一)

    父类**构造块**调用;n=10  m=10
    父类$$构造函数$$;   n=100    m=20
    父类**构造块**调用;n=10  m=40
    父类$$构造函数$$;   n=100    m=50
    父类%%静态块%%调用; m=100
    父类**构造块**调用;n=10  m=200
    父类$$构造函数$$;   n=100    m=210
    【 子类 】@@ 静态块 @@调用;    m=212
    父类**构造块**调用;n=10  m=424
    父类$$构造函数$$;   n=100    m=434
    【 子类 】^^ 构造块 ^^调用;
    n=102
    sn=5
    m=436
    【 子 类 】[[ 构造函数 ]];
    n=112
    m=446
    

    结果(二):【将main()函数的new Son()注释掉的运行结果】

    **父类**构造块**调用;n=10  m=10
    父类$$构造函数$$;   n=100    m=20
    父类**构造块**调用;n=10  m=40
    父类$$构造函数$$;   n=100    m=50
    父类%%静态块%%调用; m=100
    父类**构造块**调用;n=10  m=200
    父类$$构造函数$$;   n=100    m=210**

    结果(三):【将Father类中的两个引用p、p1注释掉的运行结果,结果二中的new Son();也注释掉】

    父类%%静态块%%调用; m=10
    父类**构造块**调用;n=10  m=20
    父类$$构造函数$$;   n=100    m=30

    结果(四):【将Father类中的两个引用p、p1注释掉的运行结果,结果二中的new Son();不注释掉】

    父类%%静态块%%调用; m=10
    父类**构造块**调用;n=10  m=20
    父类$$构造函数$$;   n=100    m=30
    【 子类 】@@ 静态块 @@调用;    m=32
    父类**构造块**调用;n=10  m=64
    父类$$构造函数$$;   n=100    m=74
    【 子类 】^^ 构造块 ^^调用;
    n=102
    sn=5
    m=76
    【 子 类 】[[ 构造函数 ]];
    n=112
    m=86
    展开全文
  • C++构造函数执行顺序

    千次阅读 2017-09-08 10:29:49
    一、先执行静态成员的构造函数,如果静态成员只是在类定义中声明了,而没有实现,是不用构造的。必须初始化后才执行构造函数。 二、任何虚拟继承基类的构造函数按照它们被继承的顺序构造(不是初始化列表中的...

    经测试按照如下顺序:

    一、先执行静态成员的构造函数,如果静态成员只是在类定义中声明了,而没有实现,是不用构造的。必须初始化后才执行其构造函数。

    二、任何虚拟继承基类的构造函数按照它们被继承的顺序构造(不是初始化列表中的顺序)

    三、任何非虚拟继承基类的构造函数按照它们被继承的顺序构造(不是初始化列表中的顺序)

    四、任何成员对象的构造函数按照它们声明的顺序构造

    五、类自己的构造函数

    测试程序如下:

    [cpp]  view plain copy
    1. #include <iostream>  
    2. #include <string>  
    3. using namespace std;  
    4.   
    5. //抽象类A  
    6. class  
    7.  
    8. public 
    9.     A()  
    10.      
    11.         cout<<"抽象类A的构造函数"<<endl;  
    12.      
    13.     //纯虚函数fun  
    14.     virtual void fun1() 0;  
    15. };  
    16.   
    17. //抽象类B  
    18. class  
    19.  
    20. public 
    21.     B()  
    22.      
    23.         cout<<"抽象类B的构造函数"<<endl;  
    24.      
    25.     //纯虚函数fun  
    26.     virtual void fun2() 0;  
    27. };  
    28.   
    29. //普通类C  
    30. class  
    31.  
    32. public 
    33.     C()  
    34.      
    35.         cout<<"类C的构造函数"<<endl;  
    36.      
    37. };  
    38.   
    39. //普通类D  
    40. class  
    41.  
    42. public 
    43.     D()  
    44.      
    45.         cout<<"类D的构造函数"<<endl;  
    46.      
    47. };  
    48.   
    49. //普通类C  
    50. class  
    51.  
    52. public 
    53.     E()  
    54.      
    55.         cout<<"类E的构造函数"<<endl;  
    56.      
    57. };  
    58.   
    59. //普通类D  
    60. class  
    61.  
    62. public 
    63.     F()  
    64.      
    65.         cout<<"类F的构造函数"<<endl;  
    66.      
    67. };  
    68.   
    69. //普通类D  
    70. class  
    71.  
    72. public 
    73.     G()  
    74.      
    75.         cout<<"类G的构造函数"<<endl;  
    76.      
    77. };  
    78.   
    79. //普通类D  
    80. class  
    81.  
    82. public 
    83.     H()  
    84.      
    85.         cout<<"类H的构造函数"<<endl;  
    86.      
    87. };  
    88. //普通类D  
    89. class  
    90.  
    91. public 
    92.     M()  
    93.      
    94.         cout<<"类M的构造函数"<<endl;  
    95.      
    96. };  
    97.   
    98. class Test: public A,public B,virtual public C,virtual public D,public E,public  
    99.  
    100. public 
    101.     Test():B(),A(),D(),C(),F(),E()  
    102.      
    103.         cout<<"类Test的构造函数"<<endl;  
    104.      
    105.     void fun1()  
    106.      
    107.      
    108.     void fun2()  
    109.      
    110.      
    111. private 
    112.     g;  
    113.     static h;  
    114.     static m;  
    115. };  
    116.   
    117. Test::h;  
    118.   
    119. int main(int argc, charargv[])  
    120.  
    121.     Test test;  
    122.     return EXIT_SUCCESS;  
    123.  
    结果:  类H的构造函数   (static 成员类,而且被初始化了)
    类C的构造函数        (虚拟继承基类)
    类D的构造函数
    抽象类A的构造函数    ( 非虚拟继承基类)
    抽象类B的构造函数
    类E的构造函数
    类F的构造函数
    类G的构造函数        (普通成员对象构造)
    类Test的构造函数      (派生类自己构造函数)
    展开全文
  • 派生类构造函数执行顺序如下:  所有基类的构造函数,多个基类构造函数的执行顺序取决于定义派生类时所指定的顺序,与派生类构造函数中所定义的成员初始化列表的参数顺序无关; 构造函数的显示初值初始化,与...

    派生类构造函数执行顺序如下:

        所有基类的构造函数,多个基类构造函数的执行顺序取决于定义派生类时所指定的顺序,与派生类构造函数中所定义的成员初始化列表的参数顺序无关;

    构造函数的显示初值初始化,与初始化列表顺序无关,而与类中成员定义顺序有关。

    如:

    class D1 :  public B1 ,public  B2
    {
    public:
    D1() :  b2 (4),B1 (1), b1(2)  ,B2 (3)
    {
    }


    B1 b1;
    B2 b2;
    };

    D1 b;

    很明显D1中先执行B1、B2的构造函数然后是D1的构造函数。如果其中有虚基类,就需要先执行虚基类的构造函数。执行D1构造函数时,初始化成员初值,根据成员定义顺序,可以看到,先初始化b1,再初始化b2.


    1.虚基类的概念
        
              在C++语言中,一个类不能被多次说明为一个派生类的直接基类,但可以不止一次地成为间接基类。这就导致了一些问题。为了方便 说明,先介绍多继承的“类格”表示法。
           
              派生类及其基类可用一有向无环图(DAG)表示,其中的箭头表示“由派生而来”。类的DAG常称为一个“类格”。复杂类格画出来通常更容易理解。例如:

    复制代码
    5-19
    class L
    { public:
    int next;

    };
    class A : public L
    { };
    class B : public L
    { };
    class C : public A, public B
    { public :
    void f()
    {
    next=0;
    }
    };
    复制代码


    这时,next有两个赋值语句next=0; 具有二义性,它是将A::next置为零,还是将B::next置为零,或者将两者都置为0,需要在函数f()中被显式的说明.
    如果希望间接基类L与其派生类的关系是如下图

     

    当在多条继承路径上有一个公共的基类,在这些路径中的某几条路经汇合处,这个公共基类就会产生多个实例。

             如果只想保存这个基类的一个实例,可以将这个公共基类说明为虚拟基类或称虚基类。
             
           它仅是简单地将关键字virtual加到基类的描述上,例如改写上述例子为例5-20


    注意!!!

     

    一个派生类的对象的地址可以直接赋给虚基类的指针,例如:
                 C  obj;
                  L  * ptr=&obj;
        这时不需要强制类型转换,并且,一个虚基类的引用可以引用一个派生类的对象,例如:  
             C  obj2;
              L &ref=obj2;
           反之则不行,无论在强制类型转换中指定什么路径,一个虚基类的指针或引用不能转换为派生类的指针或引用。例如:
            C  * P=(C*)(A*)ptr;
     将产生编译错误。

     

     

    2. 虚基类对象的初始化
            虚基类的初始化与多继承的初始化在语法上是一样的,但隐含的构造函数的调用次序有点差别。
            虚基类构造函数的调用次序是这样规定的: 
          
      1. 虚基类的构造函数在非虚基类之前调用。
            2. 若同一层次中包含多个虚基类,虚基类构造函数按它们说明的次序调用。
            3. 若虚基类由非虚基类派生,则遵守先调用基类构造函数,再调用派生类构造函数的规则。

     

    例如 :
               class  X :  public Y, virtual public Z
                   {     }
                       X one;
             将产生如下调用次序:
                      Z()
                      Y()
                      X()
             这里Z是X的虚基类,故先调用Z的构造函数,再调用Y的构造函数,最后才调用派生类X自己的构造函数。



     

    复制代码
    # include "iostream.h"       
    class base
    {
    public:
    base()
    {cout<<"Base"<<endl;}
    };
    class base2
    {
    public:
    base2()
    {cout<<"Base2"<<endl;}
    };

    class level1 : public base2, virtual public base
    {
    public:
    level1()
    {cout<<"level1"<<endl;}
    };
    class level2 : public base2, virtual public base
    {
    public:
    level2()
    {cout<<"level2"<<endl;}
    };
    class toplevel : public level1, virtual public level2
    {
    public:
    toplevel()
    {cout<<"toplevel"<<endl;}
    };
    复制代码

    当建立对象view时,将产生如下调用次序:
                level2()
                level1()
                toplevel()
         而level2()要求:
           base()
            base2()
            level2()
            level1()要求
             base2()
             level1()
            toplevel()要求
             toplevel()

     

     

    所以,构造函数的调用顺序为:
                 base()
                 base2()
                 level2()        
              base2()
                 level1()
                 toplevel()


     

     

     

     

     

    展开全文
  •  在多重继承中,派生类的构造函数与单继承下派生类构造函数相似,它必须负责该派生类所有基类构造函数以及对象成员(如果有的话)构造函数的调用。同时,派生类的参数必须包含完成所有基类、对象成
  • C++多继承构造函数执行顺序

    千次阅读 2012-11-29 22:14:56
    在C++的构造函数初始化列表里,类成员的初始化顺序与其声明顺序相同,而在类的多继承中,构造函数执行顺序便与“继承声明”顺序相同了,详见代码:   #include using namespace std; class C{ public: C(){...
  • 成员变量和构造函数执行顺序

    千次阅读 2017-11-30 13:18:19
    Java虚拟机创建一个对象都包含以下步骤。 (1)给对象分配内存。 (2)将对象的实例变量自动初始化为其变量类型的默认值。 ...(3)初始化对象,给实例变量赋予正确的初始值。...成员变量优先于构造函数
  • 在JavaSE的基础笔试题中经常会出现这三个的一个执行顺序,那么他们的执行顺序究竟是怎么样的呢?通过代码我们可以直接看一下最终结果(代码如下) public class testOne extends TestTwo{ public testOne(){ ...
  • Java中构造函数执行顺序的问题

    千次阅读 2011-11-02 16:03:37
    1, 先执行内部静态对象的构造函数,如果有多个按定义的先后顺序执行;而且静态类的构造函数只会被执行一次,只在其第一个对象创建时调用,即便是创建了同一个类的多个对象,例如main()函数里b1,b2创建了同一个类...
  • 被static修饰的变量,块,方法都是会在类被加载的时候就会执行,而且是先与构造函数执行。 public class A { { System.out.println("A 初始化块"); } static{ System.out.println("A 静态块"); ...
  • 当你知道了这些都指的是什么了,直接在程序里面写一遍不就行了,运行完记住顺序。 所以重点是记住代码都是什么样子的,怎么写的 package shunxu; public class shunxun { static class a { { System.out.println...
  • java 继承类 变量、静态变量、构造函数执行顺序class C{ static int prt(int i){ System.out.println(i); return i; }}class A{ int a=C.prt(0); static int b=C.prt(1); A(){ System.out....
  • 父类: package com.Test; public class StaticExtends { //静态代码块  static{ ... System.out.println("父类静态代码块");... //构造代码块 ... System.out.println("父类构造代码块");  }  
  • 2、load完毕父类与子类后,从main函数入口执行程序,先输出,接着new实例化Beetle类,则先实例化父类Insect,实例化父类时,先初始化非静态成员变量和非静态代码块,接着执行父类构造方法 再实例化子类,实例化子类...
  • ),然后申明类中非静态成员变量,再执行构造函数,因为构造函数中可能会使用类中的成员变量。于是第一行便是打印了 “我是静态的” ,接着是 “this is Root”  第二次实例化Root对象时,便不再执行静态代码...
  • 对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态...
  • 分析:B类无参的构造函数中的this语句并没有影响到父类A类的构造函数执行顺序 *********************************** 分割线*********************************** 实验二 ...
  • JAVA: 先执行父类的构造函数,然后是引用对象的构造函数,然后是自己的构造函数。public class Test { public static void main(String[] args) { Child child = new Child(); }}class Parent { Parent() { ...
  • package job; public class TestConsSeq { public static void main(String[] args) { ... * 1、静态成员变量为类变量,所有对象共享同一... * 2、静态成员变量的声明和定义仅在首次加载类时执行一次 *
  • 构造函数执行顺序 调用虚基类构造函数(如有多个则按虚基类声明顺序从左到右) 调用基类构造函数(如有多个则按基类声明顺序从左到右) 设定虚函数表指针值(virtual table pointer) 执行初始化列表、调用成员...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 323,563
精华内容 129,425
关键字:

构造函数执行顺序