编程语言
首页 > 编程语言> > C++继承和派生

C++继承和派生

作者:互联网

继承的概念

面对对象的语言具有四个特点:抽象,封装,继承和多态性。在上面的内容中我们已经分析了类和对象的概念,了解面对对象程序设计的两个重要特征--数据抽象与封装,已经能够设计出基于对象的程序,这个是面对对象设计的基础和需要掌握的思想。
如果要较好的面对对象进行程序的开发和设计,还必须掌握面对对象的另外两个重要的特征----继承性和多态性。

​ 继承性是面对对象程序设计的重要特征,可以说,如果没有掌握继承性的概念,就相当没有掌握面对对象编程的思想。

类与类之间的关系

在面对对象中,类与类存在三种关系,简单说明

继承关系的举例说明

万物都有继承的关系,继承是一种重要的关系,比如对于植物而言

image

每种植物都属于低等植物和高等植物中一种,所以继承高等植物或者低等植物所具有的特性,然后也拥有自己独特的特点形成一类。

继承的相关概念

其实类的一些名词和阐述可以依靠下边的一副图来说明

image

类继承的语法形式

class 派生类名:基类名表
{
	数据成员和成员函数声明
};

基类名表 构成
访问控制 基类名1,访问控制,基类名2,...访问控制 基类名n

访问控制表示类对基类的继承方式,一共用三个关键词
    public   	公有继承
    private  	私有继承
    protected 	保护继承

注意:C++中的继承方式(public、private、protected)会影响子类的对外访问属性。

继承重要说明

派生类的访问控制

​ 派生类继承了基类的全部成员函数和成员方法(除了构造函数和析构函数除外),但是这些成员的访问属性,在派生的过程中是可以进行调整,那如何进行调整,可以通过对类对基类的继承方式来进行访问控制。

​ 不同的继承方式会改变继承成员的访问属性

image

继承的访问控制图

image

继承权限的三看原则

C++中的继承方式(public、private、protected)会影响子类的对外访问属性

判断某一句话,能否被访问:

  1. 看调用语句,这句话写在子类的内部、外部
  2. 看子类如何从父类继承(public、private、protected)
  3. 看父类中的访问级别(public、private、protected)

派生类类成员访问级别设置原则

思考:如何恰当的使用public,protected和private为成员声明访问级别?

  1. 需要被外界访问的成员直接设置为public
  2. 只能在当前类中访问的成员设置为private
  3. 只能在当前类和子类中访问的成员设置为protected,protected成员的访问权限介于public和private之间

继承中构造和析构

​ 类型兼容原则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来代替。通过公共继承,派生类得到了基类中除构造函数和析构函数之外的所有成员。这样,公有派生类实际就具备基类所有功能,凡是基类能解决的问题,公有派生类都可以解决。类型兼容原则中所指的替代包括以下几种情况:

在替代之后,派生类对象就可以作为基类的对象进行使用,但是只能使用从基类继承的成员。类型兼容规则是多态性的重要基础之一。

但是对以上进行总结就是子类是特殊的父类(base *p = &child)

继承中对象模型

类在C++编译的内部都可以理解成结构体

子类是由父类成员叠加子类新成员得到的

//子类对象如何初始化父类成员
//继承中的构造和析构 
//继承和组合混搭情况下,构造函数、析构函数调用顺序研究

#include <iostream>
using namespace std;

class Object
{
public:
	Object(const char* s)
	{
		cout << "Object()" << " " << s << endl;
	}
	~Object()
	{
		cout << "~Object()" << endl;
	}
};

class Parent : public Object
{
public:
	Parent(const char* s) : Object(s)
	{
		cout << "Parent()" << " " << s << endl;
	}
	~Parent()
	{
		cout << "~Parent()" << endl;
	}
};

class Child : public Parent
{
protected:
	Object o1;
	Object o2;
public:
	Child() : o2("o2"), o1("o1"), Parent("Parameter from Child!")
	{
		cout << "Child()" << endl;
	}
	~Child()
	{
		cout << "~Child()" << endl;
	}
};

void run()
{
	Child child;
}

int main(int argc, char* argv[])
{
	cout << "demo_extend_construct_destory.cpp" << endl;
	run();
	system("pause");
	return 0;
}

得到的结果如下所示:

image

继承中的构造析构调用原则

从上面的例子我们可以了解到:

继承和组合混搭的情况下,构造和析构的调用原则

原则: 先构造父类,在构造成员变量,最后构造自己

​ 先析构自己,在析构成员变量,最后析构父类

感觉有点类型队列

继承中同名成员变量的处理方法

使用一张图来表示继承对于同名变量的处理方式
image

派生类的static关键字

如果继承和static关键字在一起会发生什么现象了

理论知识:

image

image

总结:

  1. static函数也要遵守三个访问原则
  2. static 容易没有分配内存(不但需要初始化,更重要的是显示的告诉编译器的内存分配)
  3. 构造函数默认为private

多继承

多继承的概念

class 派生类:访问控制 基类名1,访问控制,基类名2...访问控制,基类名n

{

成员函数和成员变量;

};

image

多继承的派生类构造和访问

一个多继承的案例

image

image

虚继承

如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性,比如以下的示意图所示:

image

image

继承的总结:

  1. 继承是面向对象程序设计实现软件重用的重要方法。程序员可以在已有基类的基础上定义新的派生类。
  2. 单继承的派生类只有一个基类。多继承的派生类有多个基类。
  3. 派生类对基类成员的访问由继承方式和成员性质决定。
  4. 创建派生类对象时,先调用基类构造函数初始化派生类中的基类成员。调用析构函数的次序和调用构造函数的次序相反。
  5. C++提供虚继承机制,防止类继承关系中成员访问的二义性。
  6. 多继承提供了软件重用的强大功能,也增加了程序的复杂性。

标签:派生,继承,子类,成员,派生类,C++,基类,父类
来源: https://www.cnblogs.com/Kroner/p/15780177.html