C++自学笔记(14)之继承与继承方式

1.继承的概念

继承主要是由于一些类存在包含关系,如定义了一个Person类以及Worker类,后者是前者的子集。在定义Worker类时与Person类重复的属性就不用再定义了。定义子集Worker类时形式如下 。
在这里插入图片描述
实例化之后,内存中看,在Person类中定义了名字和年龄,Worker类中没有定义这两个,但由于继承了Person,其内存中也会存在名字和年龄,以及其特有的工资。
在这里插入图片描述
在示例化子类时(如Worker)时会先实例化其父类在实例化它自己,销毁时顺序是相反的。

2.继承方式

继承方式主要分为下图中的三种方式
在这里插入图片描述

(1)公有继承

公有继承在不同访问限定符下也是不同的
先看一下不同的访问限定符的作用
在这里插入图片描述
上图中由于m_iAgem_strName分别在protectedprivate下,像右图那样调用是错误的。
在这里插入图片描述
而像这样在Person内可以调用函数对protectedprivate下的两个数据成员赋值,类外无法使用。(在不涉及继承时,protectedprivate没有区别)

①public访问限定符在公有继承中的特性

在这里插入图片描述
在使用的时候Worker可以去调用父类Person的数据成员以及成员函数。

②protected访问限定符在公有继承中的特性

在这里插入图片描述
父类的public以及protected下的成员函数和数据成员函数分别继承到了子类的publicprotected下,而且子类自定义的成员函数也可定义父类protected下的数据成员。

③private访问限定符在公有继承中的特性

在这里插入图片描述
父类的private下的成员函数会被继承到子类private下的不可见位置,像右图中那样调用m_iAge是错误的。

总结一下这三种访问限定符继承特点如下
在这里插入图片描述

(2)保护继承

在这里插入图片描述

(3)私有继承

在这里插入图片描述
在这里插入图片描述
私有继承和上图中在Lineprivate下定义的对象成员一样,只能访问公有的数据成员以及成员函数。这两种都称为Has a关系

Has a 子类只能访问父类公有的数据成员以及成员函数

3.代码例子

在这里插入图片描述
定义了一个Person

#pragma once
#include <string>
#include <iostream>
using namespace std;

class Person
{
public:
	Person()
	{
		m_strName = "Merry";
	}
	void play()
	{
		cout << "Person--play()" << endl;
		cout << m_strName << endl;
	}
protected:
	string m_strName;
};

Person类用保护继承定义了一个Soldier

#pragma once
#include "Person.h"
#include <iostream>
using namespace std;
class Soldier:protected Person   //保护继承Soldier
{
public:
	void work()
	{
		m_strName = "Jim";    //从Person继承来的数据成员
		m_iAge = 20;
		cout << m_strName << endl;
		cout << m_iAge << endl;
		cout << "Solider--work()" << endl;
	}
protected:
	int m_iAge;
};

(1)保护继承调用父类成员函数

在如下图中这样在主程序中会报错
在这里插入图片描述
因为playSoldier保护继承父类的成员函数,属于在子类的protected访问限定符下,无法被实例化调用。
但如果像这样把父类中的play添加到子类中的函数中去,再调用work时是可以显示出play的内容的。
在这里插入图片描述

(2)保护继承再公有继承调用

再定义一个类Infantry

#pragma once
#include "Soldier.h"
class Infantry:public Soldier    //从Soldier公有继承
{
public:
	void attack()
	{
		m_strName = "Jim";
		cout << m_strName << endl;
		cout << "Infantry--attack()" << endl;
	}
};

在主程序中调用如左图,其运行结果如右图。
在这里插入图片描述

(3)私有继承再公有继承调用

Soldier改为private私有继承

#pragma once
#include "Person.h"
#include <iostream>
using namespace std;
class Soldier:private Person   //私有继承Soldier
{
public:
	void work()
	{
		m_strName = "Jim";    //从Person继承来的数据成员
		m_iAge = 20;
		cout << m_strName << endl;
		cout << m_iAge << endl;
		cout << "Solider--work()" << endl;
	}
protected:
	int m_iAge;
};

这时候再实例化Infantry调用attack函数就会报错
在这里插入图片描述
这是由于m_strNamePerson父类私有继承到Soldier子类的private下,Soldier可以调用其private下的成员函数,但是Infantry作为子类从父类Solder公有继承时,是无法调用其private下的数据成员的。
(但只要子类从父类派生,子类就含有父类所有的数据成员,只是有些无法调用)

猜你喜欢

转载自blog.csdn.net/qq_39672732/article/details/89014124
今日推荐