首先看看下面代码,猜猜会输出什么?
class Member{ public Member(){ System.out.println("Member"); } } class Father{ public Father(){ System.out.println("Father."); } } public class BigProblem extends Father{ private Member member=new Member(); public BigProblem(){ System.out.println("Son."); } public static void main(String args[]){ BigProblem bigProblem=new BigProblem(); } }
输出结果是;
Father. Member Son.
原因:构造函数的执行过程是:父类的构造函数——》成员对象的构造函数——》自身的构造函数。
再看看下面这个例子,猜猜结果:
class Member{ public Member(){ System.out.println("Member"); } } class Father{ private Member member=new Member(); //被移到这里了 public Father(){ System.out.println("Father."); } } public class BigProblem extends Father{ public BigProblem(){ System.out.println("Son."); } public static void main(String args[]){ BigProblem bigProblem=new BigProblem(); } }
输出结果:
Member Father. Son.
分析:由于基类有成员对象,所以先要执行基类的成员对象的构造函数。再执行基类的构造函数,最后执行自身的构造函数。
相关推荐
派生类构造函数和析构函数的执行顺序 在面向对象编程中,继承是非常重要的一个概念。派生类可以继承基类的成员,实现代码的重复利用。但是,基类的构造函数和析构函数不能被继承。如果在派生类中需要对新增加的成员...
当一个类是另一个类的基类时,基类的构造函数会在派生类构造函数之前被调用。这是为了确保基类的部分首先被正确初始化。基类的构造函数可以通过派生类的成员初始化列表来指定: ```cpp class Base { public: ...
在这个例子中,`Circle()`是默认构造函数,没有参数,而`Circle(double r)`是带参数的构造函数,接收一个double类型的参数`r`来设定圆的半径。当我们创建`Circle`对象时,可以根据需求选择合适的构造函数: ```cpp ...
1. **基类构造函数**:如果类是其他类的派生类,那么在派生类的构造函数执行之前,基类的构造函数会先被调用。这是为了确保基类的部分首先被正确初始化。 2. **成员初始化列表**:在构造函数的初始化列表中,成员...
在这个例子中,`MyClass`的构造函数接受一个整数参数`value`,并将其赋值给类的成员变量`this->value`。当创建`MyClass`的对象时,我们需要提供一个值来调用构造函数,如`MyClass obj(10);`。 构造函数可以有多个...
在这个例子中,我们定义了一个`Student`类,包含两个构造函数(默认构造和拷贝构造)和一个析构函数。`main()`函数中创建了两个`Student`对象`randy`和`wang`。当我们调用`fn(randy)`时,`randy`作为参数传入,此时...
在此例中,当我们创建`A`对象时,`B`的构造函数会先被调用,然后才是`A`的构造函数,因为`b`是`A`的一个成员。 接下来,我们讨论析构函数的顺序。与构造函数相反,析构函数的调用遵循“后进先出”(LIFO)的原则,...
3. 调用顺序:在派生类的构造函数执行过程中,首先会调用基类的构造函数(如果有的话),然后才是派生类自身的构造函数体。这是因为对象的初始化是从基类到派生类的顺序进行的,保证了先初始化基类的部分,再初始化...
3. 构造函数的执行顺序: 在对象创建过程中,构造函数的调用顺序遵循以下规则: - 首先,按照声明顺序调用基类的构造函数。 - 如果存在虚拟基类,其对象的虚拟基指针会先被初始化。 - 如果类包含虚函数,对象的...
- 这可以通过观察构造函数的输出顺序来验证,例如,在上述例子中,"base constructor"总是先于"derived constructor"打印出来。 4. **调用父类的非默认构造函数**: - 如果子类需要调用父类的非默认构造函数,...
在类的继承体系中,构造函数的调用顺序遵循“自底向上,自顶向下”的原则,即基类的构造函数先于派生类的构造函数执行。这是因为基类的部分必须先被初始化,然后再是派生类的成员。 C++11引入了列表初始化和移动...
这是因为在构造函数执行期间,子类的部分还没有被初始化,因此虚函数表(vtable)尚未包含子类的重写。只有当基类构造函数完成后,子类部分开始构造,虚函数表才会被更新,从而允许后续的虚函数调用正确地指向子类的...
在示例代码中,`RectConstructor`类有两个构造函数:一个无参数的默认构造函数,另一个是带有长度和宽度参数的构造函数。通过这两个构造函数,我们可以创建不同尺寸的长方形对象。在`RectDemo`类的`main`方法中,...
2. **构造函数调用顺序**:在子类构造函数中,必须先调用父类的构造函数(使用`super`),然后再执行子类构造函数中的其他代码。 3. **构造函数的可访问性**:子类只能访问具有相同或更宽松访问级别的父类构造函数。...
在这个例子中,`A`类的对象在创建时通过构造函数分配了一个浮点数,而在对象销毁时,析构函数负责释放这个内存。 对于不同类型的对象,构造函数的调用时机也不同: - 局部对象:在定义对象时,构造函数会被立即调用...
如果成员对象也是一个类的实例,那么可以在初始化列表中调用其构造函数,如: ```cpp class Outer { public: Inner inner(5); // 内部类Inner的构造函数被调用,传入5 }; class Inner { public: Inner(int value...
4. `A`类构造函数执行完毕,`B`对象构造完成,类型确定为`B`。 5. 最后,通过指针`p`调用`test()`,由于`p`具有多态性,此时`func()`调用的是`B`类版本,输出`1`。 因此,构造函数中调用虚函数的行为取决于调用时刻...
#### 二、构造函数执行步骤 1. **虚基类构造函数的调用**:如果派生类有虚基类,则首先调用虚基类的构造函数。这是为了确保虚基类的部分只被初始化一次,即使它被多重继承也是如此。 2. **非虚基类构造函数的调用...