【C++grammar】继承与构造

目录

  • 1.继承
    • 1、Inheritance (继承)
    • 2、避免一个类被继承( C++11 )
    • 3、继承实例
    • 4、完整代码
    • 5、继承的优缺点是什么?
  • 2.继承中的构造函数
    • 1、 派生类继承的成员
    • 2、调用基类构造函数
  • 3.继承中的默认构造函数
    • 1、基类的无参构造函数
    • 2、由编译器自动生成的基类构造函数会不会被派生类继承?
  • 4. 构造链和析构链
    • 1、构造函数链
    • 2、析构函数链
    • 3、例1
    • 4、例2
    • 5、调用所有的构造函数和析构函数

1.继承

1、Inheritance (继承)

在这里插入图片描述
在这里插入图片描述

2、避免一个类被继承( C++11 )

class B final {};
class D : public B {};

编译后的输出是 (Visual Studio)
error C3246: “D”: 无法从“B”继承,因为它已被声明为“final”这是程序输出

3、继承实例

在这里插入图片描述

1、创建rectangle类、Circle类,从shape类继承。

class Rectangle : public Shape {......};
class Circle: public Shape {......};

2、使用基类的构造函数初始化基类的数据成员
继承之后,rectangle也获得了shape的属性和方法,这里修改rectangle类的有参初始化函数,同时也对继承过来的基类数据成员进行初始化。

Circle::Circle(double radius_, Color color_, bool filled_) : Shape{color_,filled_} {radius = radius_;
}
Rectangle::Rectangle(double w, double h, Color color_, bool filled_) :width{ w }, height{h}, Shape{ color_,filled_ } {}

4、完整代码

继承与构造test1代码附录

5、继承的优缺点是什么?

继承方便程序员使用他人写好的类来实现自己的功能,而不用重复造轮子。
坏处是有时继承过程中会继承到许多无用的信息,而且增加了程序的复杂性,容易出错。

2.继承中的构造函数

1、 派生类继承的成员

C++11:派生类不继承的特殊函数:

(1) 析构函数
(2) 友元函数

继承基类构造函数:

(1) using A::A; 继承所有基类ctor
(2) 不能仅继承指定的某个基类ctor

调用继承的构造函数

struct A { // 等价于 class A { public:A(int i) {}A(double d, int i) {}// ...
};struct B : A {  // C++11using A::A; // 继承基类所有构造函数int d{ 0 };   // 就地初始化
};int main() {B b(1);   // 调A(int i)
}

2、调用基类构造函数

若派生类成员也需要初始化,则可以在派生类构造函数中调用基类构造函数。
调用次序:
先调用基类构造函数,再调用内嵌对象构造函数,最后再执行函数体

#include<iostream>
using std::cout;
using std::endl;//task1:继承构造函数
//创建基类B及构造函数B(int),B(char)和派生类D;
//D中不继承/继承B的ctor时的效果。//task2:派生类中调用基类构造函数
//D中增加成员double x;及D(double),在D(double)初始化列表调用B(i)并初始化x//task3:派生类先调用基类ctor,再构造内嵌对象
//增加类E及E(int) ,并在D中加入E的两个对象;创建D对象观察E ctor和B ctor 次序class B {
public:B() { cout << "B()" << endl; }B(int i) { cout << "B("<< i << ")" << endl; }B(char c) { cout << "B(" << c << ")" << endl; }
};
class E {
public:E() { cout << "E()" << endl; }
};//D里面没有构造函数,所以编译器会自动生成一个默认构造函数,去调用基类的默认构造函数
class D :public B {
private://double x{ 0.0 };E e1, e2;
public://继承构造函数using B::B;D() = default;	//显示声明//D(int i):B(i){}//D(char c):B(c){}//先调用基类构造函数,再调用内嵌对象构造函数,最后再执行函数体D(double x) :e1{}, e2{}, B(static_cast<int>(x)){ cout << "D(" << x << ")" << endl;}
};int main()
{B b;D d;D d2{3.02};
}

当程序员在派生类构造函数中显式调用基类构造函数时,应将被调用基类构造函数放在派生类构造函数初始化列表中。

3.继承中的默认构造函数

1、基类的无参构造函数

若基类ctor未被显式调用,基类的默认构造函数就会被调用。
所以这种继承的,一定要小心地书写基类的默认构造函数。
在这里插入图片描述

2、由编译器自动生成的基类构造函数会不会被派生类继承?

class A {};
class B: public A {
public:using A::A;
}

编译器为基类生成的默认构造函数会不会被继承到类B中?
在B中提供有参构造函数使编译器不生成默认构造函数,这段代码可以执行成功。所以在没有其他机制的情况下,暂且认为编译器生成的A类默认构造函数被B类继承了。
C++编译器生成默认的构造函数的几种情况

4. 构造链和析构链

1、构造函数链

构造类实例会沿着继承链调用所有的基类ctor。
调用次序: base first, derive next (父先子后)。

2、析构函数链

dtor与ctor正好相反。
调用次序: derive first, base next (子先父后)

3、例1

任务1:创建类结构:Computer->PC->Desktop/Laptop以及相应的ctor/dtor
main中创建Desktop/Laptop的对象,观察ctor/dtor调用次序

#include <iostream>
using std::cout;
using std::endl;//任务1:创建类结构:Computer->PC->Desktop/Laptop以及相应的ctor/dtor
//	main中创建Desktop/Laptop的对象,观察ctor/dtor调用次序
class Computer {
public:Computer() { cout << "Computer()" << endl; }~Computer() { cout << "~Computer()" << endl; }
};
class PC : public Computer {
public:PC() { cout << "PC()" << endl; }~PC() { cout << "~PC()" << endl; }
};class Desktop : public PC {
public:Desktop() { cout << "Desktop()" << endl; }~Desktop() { cout << "~Desktop()" << endl; }
};class Laptop : public PC {
public:Laptop() { cout << "Laptop()" << endl; }~Laptop() { cout << "~Laptop()" << endl; }
};
int main()
{Desktop d();Laptop l();return 0;
}

效果:
在这里插入图片描述

4、例2

任务2:增加类Camera作为Laptop的内嵌对象c的类型
main中创建Laptop对象,观察内嵌对象c的构造与基类构造次序

#include <iostream>
using std::cout;
using std::endl;
//任务2:增加类Camera作为Laptop的内嵌对象c的类型
// main中创建Laptop对象,观察内嵌对象c的构造与基类构造次序class Computer {
public:Computer() { cout << "Computer()" << endl; }~Computer() { cout << "~Computer()" << endl; }
};
class PC : public Computer {
public:PC() { cout << "PC()" << endl; }~PC() { cout << "~PC()" << endl; }
};class Desktop : public PC {
public:Desktop() { cout << "Desktop()" << endl; }~Desktop() { cout << "~Desktop()" << endl; }
};
class Camera {
public:Camera() { cout << "Camera()" << endl; }~Camera() { cout << "~Camera()" << endl; }
};
class Laptop : public PC {
private:Camera c{};
public:Laptop() { cout << "Laptop()" << endl; }~Laptop() { cout << "~Laptop()" << endl; }
};
int main()
{Desktop d{};Laptop l{};return 0;
}

效果:
在这里插入图片描述
构造过程:在祖先类的构造函数执行完后,执行内嵌对象的构造函数,最后执行自己的构造函数。
析构过程:与继承链相反。

5、调用所有的构造函数和析构函数

我们知道,一个类可能有不止一个构造函数。
那么,能否写出一个例子,创建一个派生类对象,从而把单继承链(链无分支)上的所有类的所有构造函数和析构函数都调一遍?
使用代理构造:【C++grammar】代理构造、不可变对象、静态成员

#include <iostream>
using std::cout;
using std::endl;
class A {
public:A() : A(0) { cout << "A()" << endl; }A(int i) : A(i, 0) { cout << "A(int i)" << endl; }A(int i, int j) {num1 = i;num2 = j;average = (num1 + num2) / 2;cout << "A(int i, int j)" << endl;}
private:int num1;int num2;int average;
};
class A_child : public A {
public:A_child() { cout << "A_child()" << endl; }~A_child() { cout << "~A_child()" << endl; }
};
int main()
{A_child l{};return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377752.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言预处理

所谓预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。预处理是&#xff23;语言的一个重要功能&#xff0c; 它由预处理程序负责完成。当对一个源文件进行编译时&#xff0c; 系统将自动引用预处理程序对源程序中的预处理部分作处理&#xff0c; 处理完毕…

(转)将cocos2dx项目从VS移植到Eclipse

本文转自:http://www.cnblogs.com/Z-XML/p/3349518.html 引言&#xff1a;我们使用cocos2d-x引擎制作了一款飞行射击游戏&#xff0c;其中创新性地融入了手势识别功能。但是我们在移植过程中遇到了很多的问题&#xff0c;同时也发现网上的资料少而不全。所以在项目行将结束的时…

十二、聚类算法——相似度测量

两套学习资料都类似&#xff0c;可参考聚类算法实战 一、聚类 聚类&#xff1a;物以类聚&#xff0c;人以群分&#xff0c;是无监督学习中的一种。 没有y&#xff0c;只有x&#xff0c;把不同的x根据相似度自动的聚成好多堆儿 本质上&#xff0c;N个样本&#xff0c;映射到K个…

操作系统磁盘调度_磁盘调度| 操作系统

操作系统磁盘调度磁盘调度 (Disk Scheduling) One of the major duties of the operating is that, to use the hardware orderly and accurately. For disk drives, it has a duty of having a fast access time and disk bandwidth. Generally, bandwidth is the total numbe…

leetcode 344. 反转字符串 541. 反转字符串 II 双指针解

目录leetcode 344.反转字符串1、题目2、思考leetcode 541. 反转字符串 II1、题目2、思考leetcode 344.反转字符串 1、题目 2、思考 典型的双指针解法&#xff1a; 一个从前往后&#xff0c;一个从后往前&#xff0c;指针对应的交换即可。 class Solution { public:void reve…

关于银联在线支付和短彩信接口的开发——总结

9月份开始做用二维码做闭环的一个在线订购景区门票的项目&#xff0c;其中这样做是很好的&#xff0c;用二维码连接了线上与线下的交易和兑券。银联在线支付接口&#xff08;asp.net cs&#xff09;做的很好&#xff0c;方便调用开发。就是处理回值的时候得找个更好的方法才能显…

十三、聚类算法

六、聚类算法实战 一、聚类 聚类是一种无监督的机器学习任务&#xff0c;可以自动将数据划分为类cluster&#xff0c;因此聚类分组不需要提前被告知所划分的组应该是什么样子的。因为我们甚至可能都不知道我们在寻找什么&#xff0c;所以聚类是用于知识发现而不是预测。 聚类…

pl/sql中的赋值运算符_如何在SQL中使用AND / OR运算符?

pl/sql中的赋值运算符Basically, AND / OR operator is used to retrieving the record from the database. If we give more than one conditions by using AND Operator, then it retrieves the data from the database when both the conditions are true. And if we use OR…

【C++grammar】名字隐藏与重定义

目录1、继承中的名字隐藏1.基类同名函数被隐藏的现象描述2.问题理解3.避免现象2、重定义1.现象描述2.重定义与重载的区别3.能否使用 using 将基类成员引入到派生类定义中1、继承中的名字隐藏 1.基类同名函数被隐藏的现象描述 在学习变量作用域的时候知道&#xff0c;全局变量…

javascript 核心概念(1)-数据类型

语法 &#xff08;1&#xff09;到现在为止&#xff0c;大多数浏览器也还是支持到ECMAScript 第三版的标准。 核心概念就是一个语言的基本工作原理&#xff0c;涉及语法&#xff0c;操作符&#xff0c;数据类型。 &#xff08;2&#xff09;javascript的一切--变量&#xff0c;…

注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(五):使用@Component 来简化bean的配置...

虽然我们可以通过 Autowired 在 Bean 类中使用自动注入功能&#xff0c;但是 Bean 还是在 applicatonContext.xml 文件中通过 <bean> 进行定义 —— 在前面的例子中&#xff0c;我们还是在配置文件中定义 Bean&#xff0c;通过 Autowired为 Bean 的成员变量、方法形参或构…

c语言条件语句示例_PHP中的条件语句和示例

c语言条件语句示例PHP条件语句 (PHP Conditional Statements) While coding, you may get to a point where your results can only be gotten when a condition is valid. We make use of conditional statements. Conditional statements are statements that can only be ex…

十四、聚类实战——图片压缩

对同一像素点值的像素点归为一类&#xff0c;通过平均值进行取代&#xff0c;从而将图像进行压缩并且保证图像尽可能不失真&#xff0c;关键信息仍保留。 from PIL import Image import numpy as np from sklearn.cluster import KMeans import matplotlib import matplotlib.…

步骤菜单使用css3实现

代码库&#xff1a;http://thecodeplayer.com/walkthrough/css3-breadcrumb-navigation 有兴趣的可以看一下&#xff0c;看完绝对让你大饱眼福。首先截图&#xff0c;看效果看着很酷吧&#xff0c;其实实现起来也不是很难&#xff0c;里边需要用的技术有:box-shadow,计数器&…

【嵌入式系统】STM32串口通信的四种方法(基于RTOS)

目录1、串行通信的基本参数2、轮询方式代码效果3、中断方式代码效果4、中断加上时间戳方式代码及效果5、DMA空闲中断方式接收数据1、串行通信的基本参数 串行端口的通信方式是将字节拆分成一个接一个的位再传输出去&#xff0c;接收方再将此一个一个的位组合成原来的字符&…

大数据 java 代码示例_Java变量类型与示例

大数据 java 代码示例Java变量 (Java variables) Variables are the user-defined names of the memory blocks, and their values can be changed at any time during program execution. They play an important role in a class/program as they help in to store, retrieve…

毕业设计

位置跟踪系统工作原理&#xff08;博闻网&#xff09; http://science.bowenwang.com.cn/location-tracking.htm Azuma是这样定义增强现实的 :虚实结合 ,实时交互 ,三维注册 环境搭建&#xff1a; http://cvchina.net/thread-173-1-1.html http://blog.csdn.net/jdh99/article/…

十五、聚类的评估

一、Given Label 均一性homogeneity&#xff1a;一个簇中只包含一个类别样本&#xff0c;Precision 完整性completeness&#xff1a;同类别样本被归到同一个簇中&#xff0c;Recall 将均一性h和完整性c进行结合(二者加权平均)得到V-Measure&#xff0c;&#xff0c;β为权重 …

SQL SERVER作业的Schedules浅析

SQL SERVER作业的计划&#xff08;Schedules&#xff09;&#xff0c;如果你没仔细研究过或没有应用一些复杂的计划&#xff08;Schedules&#xff09;&#xff0c;那么你觉得SQL SERVER作业的计划(Schedules)非常好用&#xff0c;也没啥问题&#xff0c;但是我要告诉你一个“残…

leetcode 51. N 皇后 思考分析

目录题目思考AC代码题目 n 皇后问题研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 思考 首先以N4为例&#xff0c;画出解空间树的一部分&#xff1a; 根据模板&#xff1a; void backtracking(参数) {if(终止条件){存放结果…