【C++】类-派生和继承
类-派生和继承
1.基本概念
- 继承:保持已有类的特性而构造新类的过程
- 派生:在已有类的基础上新增自己的特性而产生新类的过程
2. 语法
单继承(一个父类)
/*
class 派生类名: 继承方式 基类名
{
成员声明;
}
*/
// eg:
class Derived: public Base
{
public:
Derived ();
~Derived ();
};
多继承(有多个父类)
/*
class 派生类名:继承方式1 基类名1,继承方式2 基类名2,...
{
成员声明;
}
*/
//eg:
class Derived: public Base1, private Base2
{
public:
Derived ();
~Derived ();
};
派生类的构成:
- 默认情况下继承除构造函数和析构函数以外的所有成员
- 派生类声明了一个和某基类成员同名的新成员,派生的新成员就隐藏或覆盖了外层同名成员
- 派生类增加新成员使派生类在功能上有所发展
3. 继承方式
不同继承方式的差别体现在:
- 派生类对基类成员的访问权限
- 通过派生类的对象对基类成员的访问权限


权限的优先级:public < protected < private。继承之后父类的成员在子类中的权限不低于继承方式的权限,即:
public不改变权限
protected:public——>protected
private:public, protected——>private
父类的private一直不能被子类访问
4. 类型转换
- 公有派生类对象可以被当作基类的对象使用,反之则不可。
- 派生类的对象可以隐含转换为基类对象;
- 派生类的对象可以初始化基类的引用;
- 派生类的指针可以隐含转换为基类的指针。
- 通过基类对象名、指针只能使用从基类继承的成员。
#include <iostream>
using namespace std; class Base1 { //基类Base1定义
public:
void display() const {
cout << "Base1::display()" << endl;
}
};
class Base2 : public Base1 { //公有派生类Base2定义
public:
void display() const {
cout << "Base2::display()" << endl;
}
};
class Derived : public Base2 { //公有派生类Derived定义
public:
void display() const {
cout << "Derived::display()" << endl;
}
};
void fun(Base1* ptr) { //参数为指向基类对象的指针
ptr->display(); //"对象指针->成员名"
}
int main() { //主函数
Base1 base1; //声明Base1类对象
Base2 base2; //声明Base2类对象
Derived derived; //声明Derived类对象
fun(&base1); //用Base1对象的指针调用fun函数
fun(&base2); //用Base2对象的指针调用fun函数
fun(&derived); //用Derived对象的指针调用fun函数
return 0;
}
都只能调用基类的display函数,即不要重写继承的非虚函数
5. 派生类的构造、析构函数
构造函数
默认情况下不继承基类的构造函数,使用
using Base::Base()指定继承基类构造函数,此时只能用构造函数对基类成员初始化自行定义构造函数:
- 派生类新增成员:派生类定义构造函数初始化;
- 继承来的成员:自动调用基类构造函数进行初始化;
- 派生类的构造函数需要给基类的构造函数传递参数。
语法:多继承+组合类
派生类名::派生类名(形参表):
基类名1(参数), 基类名2(参数), ..., 基类名n(参数),
本类成员(含对象成员)初始化列表
{
//其他初始化
};
构造函数的执行顺序
调用基类构造函数。
顺序按照它们被继承时声明的顺序(从左向右)。
对初始化列表中的成员进行初始化。
顺序按照它们在类中定义的顺序。
对象成员初化时自动调用其所属类的构造函数。由初始化列表提供参数。
执行派生类的构造函数体中的内容。
复制构造函数
- 一般都要为基类的复制构造函数传递参数。
- 复制构造函数只能接受一个参数,既用来初始化派生类定义的成员,也将被传递给基类的复制构造函数。
- 基类的复制构造函数形参类型是基类对象的引用,实参可以是派生类对象的引用
析构函数
- 析构函数不被继承,派生类如果需要,要自行声明析构函数。
- 声明方法与无继承关系时类的析构函数相同。
- 不需要显式地调用基类的析构函数,系统会自动隐式调用。
- 先执行派生类析构函数的函数体,再调用基类的析构函数。
#include<iostream>
using namespace std;
class Base1 {
public:
Base1(int val) {
x = val;
cout << "Calling constructor of base1..." << endl;
}
Base1(Base1& a) {
x = a.x;
cout << "Calling copy constructor of base1..." << endl;
}
~Base1() {
cout << "Calling destructor of base1..." << endl;
}
private:
int x;
};
class Base2 {
public:
Base2(int val) {
y = val;
cout << "Calling constructor of base2..." << endl;
}
Base2(Base2& b) {
y = b.y;
cout << "Calling copy constructor of base2..." << endl;
}
~Base2() {
cout << "Calling destructor of base2..." << endl;
}
private:
int y;
};
class Derived:
public Base1, public Base2 {
public:
Derived(int val1, int val2, int val3) :
Base1(val1), Base2(val2) {
cout << "Calling constructor of derived..." << endl;
z = val3;
}
Derived(Derived& c) :
Base1(c), Base2(c) {
cout << "Calling copy constructor of derived..." << endl;
z = c.z;
}
~Derived() {
cout << "Calling destructor of derived..." << endl;
}
private:
int z;
};
int main() {
Derived d(1, 2, 2);
cout << "***********************" << endl;
Derived newd(d);
cout << "***********************" << endl;
return 0;
}
输出结果:
Calling constructor of base1...
Calling constructor of base2...
Calling constructor of derived...
Calling copy constructor of base1...
Calling copy constructor of base2...
Calling copy constructor of derived...
Calling destructor of derived...
Calling destructor of base2...
Calling destructor of base1...
Calling destructor of derived...
Calling destructor of base2...
Calling destructor of base1...
【C++】类-派生和继承的更多相关文章
- C++ 虚基类 派生与继承
在学习设计模式时我就有一个疑问,关联和继承除了用法上的区别,好像在内存上并没有什么区别,继承也是父类作为了子类的元素(内存上),关联也是这样.而且关联好像更占内存一些.这就是设计模式里问题了“依赖倒转 ...
- mfc 类三种继承方式下的访问
知识点 public private protected 三种继承方式 三种继承方式的区别 public 关键字意味着在其后声明的所有成员及对象都可以访问. private 关键字意味着除了该类型的创 ...
- C++学习6-面向对象编程基础(运算符重载、类的派生与继承、命名空间)
运算符重载 重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其后要定义的运算符号共同组成.重载的运算符是遵循函数重载的选择原则,根据不同类型或不同参数来选择不同的重载运算符. 运 ...
- C++学习19 类的多继承
在前面的例子中,派生类都只有一个基类,称为单继承.除此之外,C++也支持多继承,即一个派生类可以有两个或多个基类. 多继承容易让代码逻辑复杂.思路混乱,一直备受争议,中小型项目中较少使用,后来的 Ja ...
- 24 类:组合 继承 super关键字 面向对象的三大性
组合 组合:自定义类的对象作为另外一个类的属性 class Teacher: def __init__(self, name, age): self.name = name self.age = ag ...
- Java开发笔记(四十八)类的简单继承
前面介绍了类的基本用法,主要是如何封装一个类的各项要素,包括成员属性.成员方法.构造方法等,想必大家对类的简单运用早已驾轻就熟.所谓“物以类聚,人以群分”,之所以某些事物会聚在一起,乃是因为它们拥有类 ...
- Day 5-<补充> 类的的继承和查找顺序
类的继承于查找顺序: 在py2中,不继承object的类为经典类,经典类继承查找:深度优先. 在py3中,默认继承object,所以python3中都是新式类,新式类的继承查找:广度优先. 类的特殊属 ...
- 2015/9/22 Python基础(18):组合、派生和继承
一个类被定义后,目标就是把它当成一个模块来使用,并把这些对象嵌入到你的代码中去,同其他数据类型及逻辑执行流混合使用.有两种方法可以在你的代码中利用类.第一种是组合,就是让不同的类混合并加入到其他类中, ...
- OOP2(虚函数/抽象基类/访问控制与继承)
通常情况下,如果我们不适用某个函数,则无需为该函数提供定义.但我们必须为每个虚函数都提供定义而不管它是否被用到了,这因为连编译器也无法确定到底会适用哪个虚函数 对虚函数的调用可能在运行时才被解析: 当 ...
随机推荐
- uwsgi nginx与django之间的关系以及各自的作用
首先要明确几个概念及其作用(注意大小写的区别): WSGI uWSGI uwsgi Nginx WSGI 是一种协议,不是任何包不是任何服务器,就和 TCP 协议一样.它定义了 Web 服务器和 We ...
- Hibernate 批量update数据时,怎么样做可以回滚,
Hibernate 批量update数据时,怎么样做可以回滚, 1.serviceManagerDaoImpl代码里对异常不进行try,catch抛出, 2.或者抛出throw new Runtime ...
- 创建具有root权限的账号
第一种 # guest:123456 useradd -p `openssl passwd -1 -salt 'salt' 123456` guest -o -u 0 -g root -G root ...
- SpringBoot打包实现静态文件、配置文件、jar包分离
在pom文件里面添加 <plugins> <!--定义项目的编译环境--> <plugin> <groupId>org.apache.maven.plu ...
- JAVA上传文件到FTP上
添加maven <!-- https://mvnrepository.com/artifact/commons-net/commons-net --> <dependency> ...
- 1079 - Just another Robbery
1079 - Just another Robbery PDF (English) Statistics Forum Time Limit: 4 second(s) Memory Limit: 3 ...
- SMOOTHING (LOWPASS) SPATIAL FILTERS
目录 FILTERS Box Filter Kernels Lowpass Gaussian Filter Kernels Order-Statistic (Nonlinear) Filters Go ...
- <数据结构>BinarySearchTree的基本操作总结
目录 ADT 结构声明 核心操作集 各操作实现 Find(),Insert(),Delete() Traverse():前中后.层 ADT 结构声明 #include<stdio.h> # ...
- 编写Java程序,使用 dom4j 创建一个 XML 文档,文档名为“city.xml”。注意该文档的格式和数据
查看本章节 查看作业目录 需求说明: 使用 dom4j 创建一个 XML 文档,文档名为"city.xml".该文档的格式和数据如图所示 实现思路: 创建Java项目,添加dom4 ...
- 编写Java程序,使用抽象类和抽象方法构建不同动物的扑食行为,抽象类设计
返回本章节 返回作业目录 需求说明: 不同的动物都有进食的行为,但是在进食前需要捕获到食物后才可以进食. 要求定义一个抽象的动物类,该类中有一个抽象的捕食方法,和一个非抽象的进食方法.在进食方法中调用 ...