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

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

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

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

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

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

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

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

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

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

关于构造函数的显示调用,参见下例。

class animal
{
protected:    //成员变量,声明为protected或者public,这里选择protected
	int height; //若声明为private,则不能被子类继承访问,会报错
	int weight;
public:
	animal(int height,int weight)  //带参的构造函数
	{
		this->height=height;
		this->weight=weight;
		cout<<"animal的带参构造函数被调用"<<endl;
	}
	virtual ~animal()
	{
		cout<<"animal的析构函数被调用"<<endl;
	}
};
//子类
class fish:public animal
{
public:
	fish():animal(height,weight) //显示调用父类的构造函数
	{
		cout<<"fish的构造函数被调用"<<endl;
	}
	virtual ~fish()
	{
		cout<<"fish的析构函数被调用"<<endl;
	}
};

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

注意:

如果父类只有带参的构造函数,且该带参的构造函数的参数有默认值,此时在子类中也可以不用显示的调用父类的构造函数。

// 父类的构造函数,改成带有默认值的参数, 这样在子类中就可以不用显示调用了
    animal(int height=19 ,int weight=20)  //带参的构造函数
    {
        this->height=height;
        this->weight=weight;
        cout<<"animal的带参构造函数被调用"<<endl;
    }

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

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

//父类
class animal
{
protected:    //成员变量,声明为protected或者public,这里选择protected
	int height; //若声明为private,则不能被子类继承访问,会报错
	int weight;
public:
	animal()
	{
		height=0;
		weight=0;
		cout<<"animal的无参构造函数被调用"<<endl;
	}
	animal(int height,int weight)  //带参的构造函数
	{
		this->height=height;
		this->weight=weight;
		cout<<"animal的带参构造函数被调用"<<endl;
	}
	virtual ~animal()
	{
		cout<<"animal的析构函数被调用"<<endl;
	}
};
//子类
class fish:public animal
{
public:
	fish()   //没有显示地调用父类的构造函数(无参或带参),则默认调用父类的无参构造函数
	{
		cout<<"fish的构造函数被调用"<<endl;
	}
	virtual ~fish()
	{
		cout<<"fish的析构函数被调用"<<endl;
	}
};

运行结果如下:

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

到此这篇关于c++ 子类构造函数初始化及父类构造初始化的使用的文章就介绍到这了,更多相关c++ 子类构造函数初始化及父类构造初始化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c++基础语法:构造函数初始化列表

    C++为类中提供类成员的初始化列表 类对象的构造 顺序是这样的:1.分配内存,调用构造函数 时,隐式/显示的初始化各数据 成员2.进入构造函数后在构造函数中执行一般计算 使用初始化列表有两个原因: 1.必须这样做:如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错. 复制代码 代码如下: class  ABC  .

  • 关于C++中构造函数初始化成员列表的总结

    1.只能在构造函数初始化列表初始化的成员变量的类型? a.const成员变量 b.引用类型的成员变量 c.static不能在初始化列表中进行初始化 d.类成员变量中有自定义类型的变量最好在初始化列表中进行初始化 2.初始化列表的顺序? 初始化列表的初始化顺序是依据类成员变量定义的顺序来决定的. 3.关于static const是否应该在初始化成员列表中初始化? static const为全局静态常量,全局的意思是该变量属于整个类而非某个类实例,所以不能再初始化列表中进行初始化. 以上就是小编为大

  • 浅谈c++构造函数问题,初始化和赋值问题

    默认构造函数(就是没有参数的构造函数) The Default Constructor The default constructor is the constructor used to create an object when you don't provide explicit initialization values. That is, it's the constructor used for declarations like this: Stock stock1;  // us

  • C++构造函数初始化顺序详解

    1.构造函数.析构函数与拷贝构造函数介绍 构造函数 1.构造函数不能有返回值 2.缺省构造函数时,系统将自动调用该缺省构造函数初始化对象,缺省构造函数会将所有数据成员都初始化为零或空 3.创建一个对象时,系统自动调用构造函数 析构函数 1.析构函数没有参数,也没有返回值.不能重载,也就是说,一个类中只可能定义一个析构函数 2.如果一个类中没有定义析构函数,系统也会自动生成一个默认的析构函数,为空函数,什么都不做 3.调用条件:1.在函数体内定义的对象,当函数执行结束时,该对象所在类的析构函数会被

  • c++ 构造函数的初始化列表

    首先,运行下图中的C++代码,输出是什么? 复制代码 代码如下: class A{private: int n1; int n2;public: A(): n2(0) , n1(n2 + 2) { } void Print() {  cout<<"n1:"<<n1<<",n2:"<<n2<<endl; }};int main(void){ A a; a.Print(); return 0;} 答案:输出n1

  • c++ 子类构造函数初始化及父类构造初始化的使用

    我们知道,构造方法是用来初始化类对象的.如果在类中没有显式地声明构造函数,那么编译器会自动创建一个默认的构造函数:并且这个默认的构造函数仅仅在没有显式地声明构造函数的情况下才会被创建创建. 构造函数与父类的其它成员(成员变量和成员方法)不同,它不能被子类继承.因此,在创建子类对象时,为了初始化从父类中继承来的成员变量,编译器需要调用其父类的构造函数.如果子类的构造函数没有显示地调用父类的构造函数,则默认调用父类的无参构造函数,至于什么事显式调用,在下面会详细说明!关于子类中构造函数的构造原则,总

  • Python实现子类调用父类的初始化实例

    前言 python中进行面向对象编程,当在子类的实例中调用父类的属性时,由于子类的__init__方法重写了父类的__init__方法,如果在子类中这些属性未经过初始化,使用时就会出错. 例如以下的代码: class A(object): def __init__(self): self.a = 5 def function_a(self): print('I am from A, my value is %d' % self.a) class B(A): def __init__(self):

  • 成员初始化列表与构造函数体中的区别详细解析

    论坛中回答一个别人问题 C++ Primer中在讲构造函数初始化列表的时候有这么一段话:无论是在构造函数初始化列表中初始化成员,还是在构造函数体中对它们赋值,最终结果是相同的.不同之处在于,使用构造函数初始化列表的版本初始化数据成员,没有定义初始化列表的构造函数版本在构造函数体中对数据成员赋值. 请问这里的初始化数据成员与对数据成员赋值的含义是什么?有什么区别? 我知道在数据成员有默认构造函数时是有不同的,但对其他类型的成员呢?其他类型成员的初始化和赋值有区别吗?================

  • 关于Java继承中父类和子类构造函数的问题

    Java子类在实例化时默认调用的是父类的无参构造函数,不论实例化时调用的是子类的有参还是无参构造函数, 可以参考这篇Java子类实例化总是默认调用父类的无参构造操作 1.当父类没有显式定义构造方法时, 编辑器会默认为此类添加一个隐式无参构造函数.此时子类可以有自己的无参和有参构造方法.不论实例化时调用的是子类的有参还是无参构造函数,默认调用的是父类的无参构造函数. 2.当父类有显式定义无参构造方法时, 此时子类也可以有自己的无参和有参构造方法.类似于1,同样默认隐式调用父类的无参构造方法. 3.

  • java中的this引用及对象构造初始化

    目录 1. this 引用 1.1 为什么要有this引用 1.2 什么是this引用 1.3 this引用的特性 1.4 this引用练习题 2. 对象的构造及初始化 2.1 如何初始化对象 2.2 构造方法 2.2.1 概念 2.2.2 特性 2.3 默认初始化 2.4 就地初始化 1. this 引用 1.1 为什么要有this引用 先来写一个日期类的例子: public class classCode { public int year; public int month; public

  • c#构造初始化的顺序浅析

    这个很基础的知识,但我至今才意识到它.想想也很失败. 直接上代码:很简单 复制代码 代码如下: public class Base    {        int i=0; public Base()        {            System.Console.WriteLine("我是基类构造器");        } } class Program    {        static void Main(string[] args)        {          

  • pycharm实现在子类中添加一个父类没有的属性

    我就废话不多说了,还是直接看代码吧! class Car(): """一次模拟汽车的简单尝试""" def __init__(self, make, model, year): """初始化描述汽车的属性""" self.make = make self.model = model self.year = year self.odometer_reading = 0 def get_de

  • 浅谈将子类对象赋值给父类对象

    最近对将子类对象赋值给父类对象有点心得,想和大家分享一下.但本人水平有限,请各位指正和批评. 言归正传,下面是几个小例子,请大家看一看. 测试一 父类: public class Supclass { public void print() { System.out.println("this is 父类print()方法"+"--此时对象"+this.toString()); } } 子类: public class Subclass extends Supcla

  • C++中静态初始化数组与动态初始化数组详解

    静态初始化的数组的长度必须是在程序中确定的常数,不能是由用户输入的变量 例子: int a[10];//正确 Student stud[10];//正确:Student是一个学生类 int n;cin>>n;int a[n];//错误 int n;cin>>n;Student stud[n];//错误:Student是一个学生类 动态初始化数组可以使用用户输入的变量作为数组的长度. 例子: int n; cin>>n; int *a=new int[n];//这样整数数

  • 函数外初始化与函数内初始化详细解析

    关于函数外初始化与函数内初始化之前一直分的不是太清,也不太在意.昨天终于出现了这方面的问题,所以决定好好看下,以下是这次的一些收获,先看测试代码: 复制代码 代码如下: #include "stdafx.h"#include <iostream>using namespace std;bool FillStr(char *&szDst, int nSize){ bool bRet = false; if (nSize > 0) {  szDst = (char

随机推荐