参考:http://www.weixueyuan.net/view/6364.html

总结:

  派生类构造函数可以自动调用基类的默认构造函数而无需显式调用。

  生类构造函数可以自动调用基类的默认构造函数,但是前提是默认构造函数必须存在。

  当基类没有默认构造函数时,派生类则无法自动调用基类的默认构造函数了。遇到这种情况有两种解决方案:其一,在基类中定义一个默认构造函数(不带参数的构造函数),例如上一节中的例2;其二,派生类中的每一个构造函数都显式的调用基类中的带参构造函数。

  建议在设计类的时候为每一个类设计一个默认构造函数,毕竟默认构造函数并不会妨碍构造函数的显式调用。

  在创建派生类对象时,必须显式或隐式地调用基类的某一个构造函数 

派生类构造函数可以自动调用基类的默认构造函数而无需显式调用。例如在上一节例2中,我们如果将condingbook类中的默认构造函数codingbook():book(){lang = none;}语句修改为codingbook(){lang = none;},则这个程序运行结果依然保持不变,因为派生类的构造函数会自动调用基类的默认构造函数。

派生类构造函数可以自动调用基类的默认构造函数,但是前提是默认构造函数必须存在。通常情况下,默认构造函数系统会自动生成的,但是如果在基类中,我们自己定义了一个带参数的构造函数,这个时候,系统是不会为基类自动生成默认构造函数的,这个时候派生类则无法自动调用基类的默认构造函数了,因为基类根本就不存在默认构造函数。遇到这种情况有两种解决方案:其一,在基类中定义一个默认构造函数(不带参数的构造函数),例如上一节中的例2;其二,派生类中的每一个构造函数都显式的调用基类中的带参构造函数。

例1:

class base
{
public:
base(int a){x = a; y = ;}
base(int a, int b){x = a; y = b;}
private:
int x;
int y;
}; class derived: public base
{
public:
derived(){z = ;}
derived(int c){z = c;}
private:
int z;
};

我们来看一下这个例子,这个例子里面先定义了一个类base作为基类,基类中拥有两个成员变量x和y,同时定义了两个带参数的构造函数,两个都是带参构造函数,如此一来类base就不会自动生成默认构造函数了。再来看派生类定义,派生类中新增了成员变量z,并且定义了一个带参构造函数和一个默认构造函数。但是如此定义,编译器会提示语法错误,因为派生类的构造函数没有显示调用基类构造函数。解决这个问题的方法在上面说了,一个是在基类自己定义一个默认构造函数,另外一种方法是显示调用基类构造函数。当然在设计类的时候推荐使用后者,毕竟构造函数就是为了初始化成员变量的,如果不显式调用基类构造函数,则从基类中继承过来的成员变量将得不到初始化,这一般来说都不是我们所希望看到的。

同时,我们还建议在设计类的时候为每一个类设计一个默认构造函数,毕竟默认构造函数并不会妨碍构造函数的显式调用。通常我们还会遇到这样一种情况,派生类中并未显式定义构造函数,这个时候派生类中只有系统自动生成的默认构造函数,如此一来,如果我们不为基类设计一个默认构造函数,则程序就会编译出错。这种错误很玄妙,如果不小心还真是难以发现。为了避免这种情况的发生,我们建议为每一个类设计一个默认构造函数。

根据以上两点建议,我们将例1进行修改,正确代码如下。

例2:

#include<iostream>
using namespace std; class base
{
public:
base(){x = ; y = ;}
base(int a){x = a; y = ;}
base(int a, int b){x = a; y = b;}
private:
int x;
int y;
}; class derived: public base
{
public:
derived():base(){z = ;}
derived(int a, int b, int c):base(a,b){z = c;}
private:
int z;
}; int main()
{
derived A;
derived B(,,);
return ;
}

在这个例子中,我们将例1中出现的问题采用双管齐下的方式解决了,为基类定义了默认构造函数,并且在派生类中显式地调用基类中的构造函数。

总的来说,在创建派生类对象时,必须显式或隐式地调用基类的某一个构造函数,这一点非常重要。当然被调用的基类的构造函数可以是带参构造函数,也可以是默认构造函数。

3.7 C++派生类构造函数调用规则的更多相关文章

  1. C++派生类构造函数调用顺序(详解)

    我们来看下面一段代码: class B1 { public: B1(int i) {cout<<"constructing B1 "<<i<<e ...

  2. C++ //构造函数调用规则 //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) //析构函数(空实现) //拷贝函数(值拷贝) //2.如果我们写了有参构造函数 编译器就不会提供默认构造函数 但是会提供拷贝构造函数 //3.如果我们写了拷贝函数 编译器就不再提供 默认 有参 构造函数

    //构造函数调用规则 #include <iostream> using namespace std; //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) ...

  3. 《从零开始学Swift》学习笔记(Day 42)——构造函数调用规则

    原创文章,欢迎转载.转载请注明:关东升的博客 在构造函数中可以使用构造函数代理帮助完成部分构造工作.类构造函数代理分为横向代理和向上代理,横向代理只能在发生在同一类内部,这种构造函数称为便利构造函数. ...

  4. C++学习17派生类的构造函数

    基类的构造函数不能被继承,在声明派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数来完成.所以在设计派生类的构造函数时,不仅要考虑派生类新增的成员变量,还要考虑基类的成员变量,要让它们都 ...

  5. c++ 派生类的构造函数 与 基类构造函数的关系

    <面向对象程序设计基础(第二版>李师贤等,第254页:C++语言的基本规则是:创建一个派生类的对象时,如果基类带有构造函数,则先调用基类的构造函数,然后才调用派生类的构造函数. <T ...

  6. C++中的类继承(2)派生类的默认成员函数

    在继承关系里面, 在派生类中如果没有显示定义这六个成员 函数, 编译系统则会默认合成这六个默认的成员函数. 构造函数. 调用关系先看一段代码: class Base { public : Base() ...

  7. C++:派生类的构造函数和析构函数

    4.2 派生类的构造函数和析构函数4.2.1 派生类构造函数和析构函数的执行顺序 通常情况下,当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数:当撤销派生类对象时,则先执行派生类 ...

  8. C++ | 继承(基类,父类,超类),(派生类,子类)

    转载:https://blog.csdn.net/Sherlock_Homles/article/details/82927515 文章参考:https://blog.csdn.net/war1111 ...

  9. C++ 派生类构造函数和析构函数

    几个问题 一个类的各数据成员的构造顺序? 按他们在类定义中出现的先后顺序:先定义者先构造. 类的对象成员的构造函数与类自身的构造函数的执行顺序? 先执行对象成员的构造函数,再执行类自身的构造函数. 构 ...

随机推荐

  1. SpringBoot集成TkMybatis插件

    前提: 基于SpringBoot项目,正常集成Mybatis后,为了简化sql语句的编写,甚至达到无mapper.xml文件. 在本篇总结教程,不在进行SpringBoot集成Mybatis的概述. ...

  2. 《HTTP 权威指南》笔记:第三章 HTTP 报文

    如果说 HTTP 是因特网的信使,那么 HTTP 报文就是它用来搬东西的包了. 这一章讲述关于 HTTP 报文的相关知识,包括: HTTP 报文的三个组成部分 请求报文以及其各种功能 响应报文以及各种 ...

  3. JavaScript 第七章总结

    前言 主要介绍了关于 JavaScript 中有关 type 的问题.讲了很多关于各种 type 的 idiosyncrasies. 谈谈JavaScript types 在 JavaScript 中 ...

  4. 2017-2018-2 20165303 实验二《Java面向对象程序设计》实验报告

    实验一 实验要求 参考 http://www.cnblogs.com/rocedu/p/6371315.html#SECUNITTEST 完成单元测试的学习 提交最后三个JUnit测试用例(正常情况, ...

  5. Linux下安装 jdk

    转自 http://www.cnblogs.com/shihaiming/p/5809553.html 0.下载jdk8 登录网址:http://www.oracle.com/technetwork/ ...

  6. codeforces 848B Rooter's Song 思维题

    http://codeforces.com/problemset/problem/848/B 给定一个二维坐标系,点从横轴或纵轴垂直于发射的坐标轴射入(0,0)-(w,h)的矩形空间.给出点发射的坐标 ...

  7. android -------- ConstraintLayout介绍 (一)

    ConstraintLayout 翻译为 约束布局,也有人把它称作 增强型的相对布局,由 2016 年 Google I/O 推出. 扁平式的布局方式,无任何嵌套,减少布局的层级,优化渲染性能.从支持 ...

  8. vue methods computed watch区别

    一.methods和computed computed是计算属性,methods是方法. html: <p>Reversed message: "{{ reversedMessa ...

  9. 解决audio 在部分移动端浏览器不能自动播放(目前包括ios、微博)

    问题描述:项目需要在页面加载完成后自动播放音乐,但在ios中却无法自动播放,需要用户主动触发 解决办法: $('html').one('touchstart',function(){ document ...

  10. 内存池、进程池、线程池介绍及线程池C++实现

    本文转载于:https://blog.csdn.net/ywcpig/article/details/52557080 内存池 平常我们使用new.malloc在堆区申请一块内存,但由于每次申请的内存 ...