c++继承详解

系列文章目录


前言

继承是面向对象编程的三大特性之一,另外两个是封装和多态。继承允许一个类(派生类)继承另一个类(基类)的成员变量和成员函数,这样可以实现代码复用和层次化设计。


一、继承的概念及定义

1 .1 概念

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许我们在保持原有类特性的基础上进行扩展,增加方法(成员函数)和属性(成员变量),这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的函数层次的复用,继承是类设计层次的复用。
下面我们看到没有继承之前我们设计了两个类Student和Teacher,student和Teacher都有姓名/地址/电话/年龄等成员变量,都有identity⾝份认证的成员函数,设计到两个类里面就是冗余的。当然他们也有⼀些不同的成员变量和函数,比如***老师*** 独有成员变量是***职称***,学生***的独有成员变量是***学号;学⽣的独有成员函数是***学习***,⽼师的独有成员函数是***授课***

下面把老师和学生中重复的内容(成员函数,成员变量)放到person基类中,student和teacher复用即可。

class Person
{
   
public:
	// 进入校园/图书馆/实验室刷二维码等身份认证
	void identity()
	{
   
		cout << "void identity()" << _name << endl;
	}
protected:
	string _name = "张三"; // 姓名
	string _address; // 地址
	string _tel; // 电话
	int _age = 18; // 年龄
};
    学生
class Student : public Person
{
   
public:
	// 学习
	void study()
	{
   
		//...
		identity();
	}
protected:
	int _stuid; // 学号
};
    老师 
class Teacher : public Person
{
   
public:
	// 授课
	void teaching()
	{
   
		//...
	}
protected:
	string title; // 职称
};

int main()
{
   
	Student s;
	Teacher t;

	s.identity();
	t.identity();

	return 0;
}

1 .2 定义

下⾯我们看到Person是基类,也称作父类。Student是派生类,也称作子类。(因为翻译的原因,所以既可以叫基类/派生类,也可以叫父类/子类。这两种叫法都可);

  1. 基本语法格式:
class DerivedClass : access-specifier BaseClass {
   
    // 成员声明
};
  • access-specifier:访问修饰符(public/protected/private)

c++继承详解_第1张图片

c++继承详解_第2张图片

1 .3 继承基类成员访问方式的变化

c++继承详解_第3张图片

  • 基类private成员在派⽣类中⽆论以什么⽅式继承都是不可⻅的。这⾥的不可⻅是指基类的私有成员还是被继承到了派⽣类对象中,但是语法上限制派⽣类对象不管在类⾥⾯还是类外⾯都不能去访问它。
  • 基类private成员在派⽣类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派⽣类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。
  • 实际上⾯的表格我们进⾏⼀下总结会发现,基类的私有成员在派⽣类都是不可⻅。基类的其他成员在派⽣类的访问⽅式==Min(成员在基类的访问限定符,继承⽅式),public > protected > private。
  • 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。
  • 在实际运⽤中⼀般使⽤都是public继承,⼏乎很少用protetced/private继承,也不提倡使⽤protetced/private继承,因为protetced/private继承下来的成员都只能在派⽣类的类⾥⾯使⽤,实际中扩展维护性不强。

1 .4 继承类模板

继承类模板允许一个类从一个模板类派生,从而继承了模板类的所有成员和特性。继承类模板可以通过继承类模板的方式创建一个新的模板类,并可以在派生类中使用父类模板的成员和方法。

namespace bit
{
   
	// stack和vector的关系,既符合is-a,也符合has-a
	template<class T>
	class stack : public std::vector<T>
	{
   
	public:
		void push(const T& x)
		{
   
			// 基类是类模板时,需要指定一下类域,
			// 否则编译报错:error C3861: “push_back”: 找不到标识符
			// 因为stack实例化时,也实例化vector
			// 但是模版是按需实例化,push_back等成员函数未实例化,所以找不到
			vector<T>::push_back(x);
			//push_back(x);
		}

		void pop()
		{
   
			vector<T>::pop_back();
		}

		const T& top()
		{
   
			return ve

你可能感兴趣的:(c++进阶,c++)