c++ 子类构造函数初始化及父类构造初始化

  我们知道,构造方法是用来初始化类对象的。如果在类中没有显式地声明构造函数,那么编译器会自动创建一个默认的构造函数;并且这个默认的构造函数仅仅在没有显式地声明构造函数的情况下才会被创建创建。

  构造函数与父类的其它成员(成员变量和成员方法)不同,它不能被子类继承。因此,在创建子类对象时,为了初始化从父类中继承来的成员变量,编译器需要调用其父类的构造函数。如果子类的构造函数没有显示地调用父类的构造函数,则默认调用父类的无参构造函数,至于什么事显式调用,在下面会详细说明!关于子类中构造函数的构造原则,总结如下,欢迎大家指导与批评。

  1.父类没有声明构造函数

    (1)子类也没有声明自己的构造函数,则父类和子类均由编译器生成默认的构造函数。

    (2)子类中声明了构造函数(无参或者带参),则子类的构造函数可以写成任何形式,不用顾忌父类的构造函数。在创建子类对象时,先调用父类默认的构造函数(编译器自动生成),再调用子类的构造函数。

  2.父类只声明了无参构造函数

    如果子类的构造函数没有显式地调用父类的构造,则将会调用父类的无参构造函数。也就是说,父类的无参构造函数将会被隐式地调用。

  3.父类只声明了带参构造函数

    在这种情况下,要特别注意。因为父类只有带参的构造函数,所以如果子类中的构造函数没有显示地调用父类的带参构造函数,则会报错,所以必需显示地调用。关于构造函数的显示调用,参见下例。

 1 class animal
 2 {
 3 protected:       //成员变量,声明为protected或者public,这里选择protected
 4     int height;  //若声明为private,则不能被子类继承访问,会报错
 5     int weight;
 6 public:
 7     animal(int height,int weight)   //带参的构造函数
 8     {
 9         this->height=height;
10         this->weight=weight;
11         cout<<"animal的带参构造函数被调用"<<endl;
12     }
13     virtual ~animal()
14     {
15         cout<<"animal的析构函数被调用"<<endl;
16     }
17 };
18 //子类
19 class fish:public animal
20 {
21 public:
22     fish():animal(height,weight) //显示调用父类的构造函数
23     {
24         cout<<"fish的构造函数被调用"<<endl;
25     }
26     virtual ~fish()
27     {
28         cout<<"fish的析构函数被调用"<<endl;
29     }
30 };

  在子类fish的构造函数中,加上一个冒号(:),然后加上父类的带参构造函数,这就是父类构造函数的显式调用。这样,在子类的构造函数被调用时,系统就会去调用父类的带参构造函数,从而实现初始化父类的成员变量。运行结果如下:

  4.父类同时声明了无参和带参构造函数

    在这种情况下,子类只需要实现父类的一个构造函数即可,不管是无参的还是带参的构造函数。如果子类的构造函数没有显示地调用父类的构造函数(无参或带参),则默认调用父类的无参构造函数。

 1 //父类
 2 class animal
 3 {
 4 protected:       //成员变量,声明为protected或者public,这里选择protected
 5     int height;  //若声明为private,则不能被子类继承访问,会报错
 6     int weight;
 7 public:
 8     animal()
 9     {
10         height=0;
11         weight=0;
12         cout<<"animal的无参构造函数被调用"<<endl;
13     }
14     animal(int height,int weight)   //带参的构造函数
15     {
16         this->height=height;
17         this->weight=weight;
18         cout<<"animal的带参构造函数被调用"<<endl;
19     }
20     virtual ~animal()
21     {
22         cout<<"animal的析构函数被调用"<<endl;
23     }
24 };
25 //子类
26 class fish:public animal
27 {
28 public:
29     fish()     //没有显示地调用父类的构造函数(无参或带参),则默认调用父类的无参构造函数
30     {
31         cout<<"fish的构造函数被调用"<<endl;
32     }
33     virtual ~fish()
34     {
35         cout<<"fish的析构函数被调用"<<endl;
36     }
37 };

  运行结果如下:

  总结以上几条,可以归纳出C++中子类继承父类时构造函数的写法的规律:当父类有显式地声明了构造函数时,子类最低限度的实现父类中的一个;当父类没有声明构造函数时,子类可以不声明构造函数或者任意地书写构造函数。

原文地址:https://www.cnblogs.com/clovershell/p/10246629.html

时间: 2024-11-18 09:47:14

c++ 子类构造函数初始化及父类构造初始化的相关文章

Effective JavaScript Item 38 在子类构造函数中调用父类构造函数

本系列作为Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中,都会有场景(Scene)这一概念.在一个场景中会包含一个对象集合,这些对象被称为角色(Actor).而每个角色根据其类型会有一个图像用来表示,同时场景也需要保存一个底层图形展示对象的引用,被称为上下文(Context): function Scene(context, width, height, images) { this.context = context; this.width = width

Java的初始化块、静态初始化块、构造函数的执行顺序及用途探究

随笔- 40  文章- 0  评论- 1 Java的初始化块.静态初始化块.构造函数的执行顺序及用途探究 Java与C++有一个不同之处在于,Java不但有构造函数,还有一个”初始化块“(Initialization Block)的概念.下面探究一下它的执行顺序与可能的用途. 执行顺序 首先定义A, B, C三个类用作测试,其中B继承了A,C又继承了B,并分别给它们加上静态初始化块.非静态初始化块和构造函数,里面都是一句简单的输出. 主类Main里面也如法炮制. 1 class A { 2 st

子父类 构造代码块 静态代码块 初始化过程

1 class Fu{ 2 Fu(){//调用show方法 被子类重写 num=0; 3 System.out.println("Fu constructor....."); 4 show();//实际是子类方法//zi..show 0 5 } 6 static{ 7 8 System.out.println("fu静态代码块"); 9 } 10 { 11 System.out.println("FU构造代码块"); 12 } 13 void

验证当多个类之间有继承关系时,创建子类对象会导致父类初始化块的执行。

结果:当多个类之间有继承关系时,创建子类对象会导致父类初始化块的执行.

父类与子类 构造函数 变量 加载顺序

http://www.cnblogs.com/mailingfeng/archive/2012/11/23/2784258.html 父的成员变量->构造方法->子的成员变量->子的构造方法注意 如果父亲的构造方法中有被子类覆盖的init方法,当调用init方法的时候由于子的成员变量还未赋值,所以init中使用已经定义的成员变量进行操作是不正确的,把成员 new出来当然没问题啦.使用子的定义的函数当然没关系啦,因为函数是被声明的的. 声明的可以拿来new 赋值,未被初始化的定义不能用的.

在C++中子类继承和调用父类的构造函数方法

构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法).因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法. 如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没有显式地声明构造函数情况下创建. 构造原则如下: 1. 如果子类没有定义构造方法,则调用父类的无参数的构造方法. 2. 如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,

子类构造函数会默认调用父类无参构造函数

1.调用父类无参构造函数是默认的! 子类的构造方法默认都去访问了父类的无参构造方法:在子类中的构造方法后都有一行默认语句 base() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Fu {   public Fu()     {         Console.WriteLine("fu");     } } class Zi : Fu {     public Zi()         : base()//不管是否显式调用,控制台都会输出fu

new子类会先运行父类的构造函数

发现子类构造函数运行时,先运行了父类的构造函数.为什么呢? 原因:子类的所有构造函数中的第一行,其实都有一条隐身的语句super(); super(): 表示父类的构造函数,并会调用于参数相对应的父类中的构造函数.而super():是在调用父类中空参数的构造函数. 为什么子类对象初始化时,都需要调用父类中的函数?(为什么要在子类构造函数的第一行加入这个super()?) 因为子类继承父类,会继承到父类中的数据,所以必须要看父类是如何对自己的数据进行初始化的.所以子类在进行对象初始化时,先调用父类

C++ 初始化形式、变量初始化规则、类构造函数的初始化列表

类构造函数的初始化列表,举例 一个对象的构造分两部分,首先是分配空间,然后初始化. 只要有对象生成,不管是以什么形式生成,都会调用构造函数进行初始化. 然后下面有个例子,在蓝色区域Big类的复制构造函数中,使用初始化列表进行成员的初始化(方法1)没有问题,而如果不使用初始化列表.直接在函数里用里面注释掉的代码(方法2)则会报错:Base类没有合适的构造函数. // W3-课程作业2-4.cpp : Defines the entry point for the console applicati