一、类继承与构造函数

在C++中,无论类是否有继承关系,每个类各自控制它自己的成员的初始化。子类虽然含有基类的成员,但是并不能对基类的成员直接初始化,需要使用基类的构造函数初始化子类中的基类部分。

从语法上说,可以在子类的构造函数的函数体中给基类的protected或public成员赋值,但是最好不要这样做

子类初始化时,会先调用基类的构造函数,初始化基类的部分并,然后按照子类成员在类中的声明顺序逐个初始化子类部分

示例

class base
{
public:base():bpub(0),bpro(0),bpri(0){cout<<__func__<<endl;}base(int init):bpub(0),bpro(0),bpri(0){cout<<"base(int init)"<<endl;}~base(){cout<<__func__<<endl;}int bpub; protected:int bpro;private:int bpri;};class derive:public base
{
public:derive(){cout<<__func__<<endl;}~derive(){cout<<__func__<<endl;}int dpub; protected:int dpro;private:int dpri;};class derive2:public base
{
public:derive2():base(),d2pub(-1),d2pro(-1),d2pri(-1){cout<<__func__<<endl;}derive2(int init):base(init),d2pub(-1),d2pro(-1),d2pri(-1){cout<<"derive2(int init)"<<endl;}~derive2() {cout<<__func__<<endl;}int d2pub; protected:int d2pro;private:int d2pri;
};int main(int argc, char const *argv[])
{derive d;derive2 d21;derive2 d22(10);return 0;
}

上述代码演示了如何在子类的构造函数中显示指定要调用基类的构造函数

输出结果表示:

1、就算在子类的构造函数中不显式指定调用基类的构造函数,当创建子类对象(derive)时,会先调用基类的默认构造函数并对基类部分进行默认初始化。

2、定义类时,可以将子类构造函数的形参传给基类的构造函数

二、类继承与拷贝构造函数

如果想在拷贝子类对象时,对基类的成员也进行拷贝,需要在子类的拷贝构造函数的初始化列表中显示调用基类的拷贝构造函数。如果不显示定义基类的拷贝构造函数,那么在对子类进行拷贝构造操作时,会先调用基类的构造函数

示例

class base2
{
public:base2(){cout<<__func__<<endl;}base2(const base2 &b2):memb(b2.memb){cout<<"base2(const base2 &b2)"<<endl;}~base2(){cout<<__func__<<endl;}int memb;
};class derive2:public base2
{
public:derive2(){cout<<__func__<<endl;}~derive2(){cout<<__func__<<endl;}derive2(const derive2 &d2):base2(d2), memd(d2.memd) {cout<<"derive2(const derive2 &d2)"<<endl;}int memd;
};int main(int argc, char const *argv[])
{derive2 d2;derive2 b2t=d2;return 0;
}

如果想在拷贝子类对象时,对基类的成员也进行拷贝,需要在子类的拷贝构造函数的初始化列表中显示调用基类的拷贝构造函数。这样,当对一个子类进行拷贝初始化时,也会先调用基类的拷贝构造函数,对子类中的基类部分进行拷贝初始化,然后再调用子类的拷贝构造函数进行对子类部分进行拷贝初始化

如果不显示调用基类的拷贝构造函数,那么在对子类进行拷贝构造操作时,会先调用基类的构造函数,将上述代码中的第5行注释掉的输出结果如下

所以,如果要定义子类的拷贝构造函数,请在子类的拷贝构造函数的初始化列表中显示调用基类的拷贝构造函数,然后再对子类的成员进行初始化

如果没有显式定义子类的拷贝构造函数,那么一般情况下,编译器会默认生成一个,此时对子类对象进行拷贝初始化也会调用基类的拷贝构造函数

三、类继承与operator=

和拷贝构造函数一样,子类的operator=必须显示调用基类的operator=

示例

在拷贝构造函数的示例代码中分别添加基类和子类的operator=

class base2
{
public://....base2 &operator=(const base2 &b2){memb=b2.memb;return *this;}int memb;
};class derive2:public base2
{
public://....derive2 &operator=(const derive2 &d2){base2::operator=(d2);memd=d2.memd;return *this;}int memd;
};int main(int argc, char const *argv[])
{derive2 d2;derive2 b2t;b2t=d2;return 0;
}

如果不显示调用基类的operator=,那么子类对象的基类部分将不会被赋值

如果子类没有显示定义operator=,那么编译器一般情况会默认生成一个operator=,此时对子类对象进行赋值时,会调用基类的operator=

四、类继承与析构函数

根据上面的输出结果可以知道,对象销毁的顺序和对象创建的顺序是相反的,一个子类对象销毁时,会先执行子类的析构函数,然后是基类的析构函数,以此类推,直至最上面的基类

虽然子类对象被释放时,会分别调用子类和基类的析构函数,但是,子类的析构函数只负责释放子类的成员所占有的资源,子类中对应的基类部分由基类的析构函数进行释放

参考

《C++ Primer》

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

C++知识点49——类继承与类的构造、拷贝、operator=和析构函数相关推荐

  1. Java面向对象编程入门练习:Manager类继承Employee类并实现求得员工平均业绩

    Java面向对象编程入门练习:Manager类继承Employee类并实现求得员工平均业绩 请定义一个Manager类,该类继承Employee类,并定义两个变量及一个构造方法,两个变量:depart ...

  2. 学习笔记,初学者对继承、接口的习题练习: 模拟给所有员工发工资定义员工Employee类,经理Manager类继承Employee类,职员Clerk类继承Employee类。

    继承.接口: 习题要求: 模拟给所有员工发工资. * 定义员工Employee类,经理Manager类继承Employee类,职员Clerk类继承Employee类. * 定义Money接口,定义公司 ...

  3. 【c++】模板类继承模板类

    C++继承访问权限:https://www.runoob.com/cplusplus/cpp-inheritance.html 1. 普通类继承 demo #include <iostream& ...

  4. c++ map 析构函数_C++|类继承关系中的虚函数、虚析构函数、虚基类

    在继承关系中,虚函数.虚析构函数.虚基类中使用的关键字virtual都是在告诉编译器,此处要进行特殊处理: 虚函数:函数重写时的要求编译器动态绑定来实现多多态 : 虚析构函数:当基类指针指向在堆内实现 ...

  5. Swift项目中不能定义OC类继承Swift类

    2019独角兽企业重金招聘Python工程师标准>>> 报错原因 Swift项目中 OC文件类  继承  Swift文件类 Cannot subclass a class with ...

  6. Ext学习笔记02 - 构造方法,类继承,类实例方法重写

    刚刚走了个大弯路,朋友们见笑,我这见识实在太少了,开始想找个有语法提示的IDE,就直接想到了Aptana,下载一个最新版本,然后就弹出来一大堆东西要更新,更新就更新吧,更新一半就报错,看他给的提示,说 ...

  7. C++的类继承与类模板

    类继承是面向对象编程中很重要(也是很难)的内容,其能有效地提高代码复用水平,提高开发的效率. 目录 基本概念 公有继承 私有继承.保护继承 包含 多重继承 类模板 基本概念 继承的种类与特点 C++中 ...

  8. python 类继承object_Python类继承对象

    小编典典 是否有理由要声明类声明object? 在Python 3中,除了Python 2和3之间的兼容性之外,没有任何理由.在Python 2中,原因很多. Python 2.x故事: 在Pytho ...

  9. C++知识点48——类继承与类的作用域

    一.静态类型决定了可访问的成员 基类的对象.指针和引用的静态类型决定了可以访问哪些成员,即使通过基类的指针或者引用指向一个子类对象,也不能通过基类的指针或引用访问子类对象的成员 示例 class ba ...

最新文章

  1. 英特尔nuc能代替主机吗_制砂机生产的沙子可靠吗?能代替天然沙子吗?
  2. iOS点滴- ViewController详解
  3. k8s通过label来控制pod的位置
  4. leetcode945. 使数组唯一的最小增量(排序)
  5. matlab图像去毛刺_警微圈 图像处理第三讲CLAHE
  6. 安兔兔2月Android手机性价比榜出炉:Redmi包揽前三
  7. hibernate之初学复合主键
  8. 黑客利用智能灯泡窃取用户数据!
  9. 线性基(bzoj 2460: [BeiJing2011]元素)
  10. .Net中的设计模式——Strategy模式
  11. 《剑指offer》面试题20——顺时针打印矩阵(C++)
  12. 自己做的PPT试题或其它文件模板有时被系统还原成原来默认的样子,如何解决?
  13. Pyside2中嵌入Matplotlib的绘图并保存(指定Graphics View)
  14. 哔哩哔哩助手:bilibili综合辅助扩展Chrome插件
  15. python向量运算_Python线性代数学习笔记——向量的基本运算,以及Python代码的实现...
  16. 工业农业消防自动检测及报警云方案
  17. 弱威胁感知时代的企业安全--360安全实战
  18. 谁动了我的奶酪之奶酪墙上的话。
  19. Spark入门-什么是Spark
  20. Hive报错:Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask MapReduce

热门文章

  1. 《MySQL技术内幕:InnoDB存储引擎第2版》——3.1 参数文件
  2. DDR的前世与今生(一)
  3. 安卓模拟器BlueStacks 安装使用教程(图解)
  4. 浅谈千万级PV/IP规模高性能高并发网站架构
  5. 清理多个varnish服务器缓存的脚本
  6. python读取压缩包中csv文件
  7. [APB VNext 笔记] UI
  8. BigDecimal 类型转换、运算、比较
  9. 【二维树状数组】See you~
  10. Latex编译过程中遇到的奇奇怪怪的问题及解决方案