详细介绍:C++篇(11)继承

一、继承的概念及定义

1.1 继承的概念

继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许我们在保持原有类的基础上进行拓展,增加方法(成员函数)和属性(成员变量),从而产生新的类,称为派生类。继承是类设计层次的复用。

比如下面,我们把公共的成员都放到Person类当中,Student和Teacher类都继承了Person,就可以复用这些成员。

#define  _CRT_SECURE_NO_WARNINGS 1
#include 
using namespace std;
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()
	{
		//...
	}
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是派生类(也称为子类

基类的private成员在派生类中都是不可见的,这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问。如果基类成员不想在类外面直接被访问,但是需要在派生类中访问,就定义为protected。

在实际运用中一般都是public继承,几乎很少使用protected/private继承,因为protected/private继承下来的成员都只能在派生类里面使用,实际中拓展维护性不强。

1.3 继承类模板

当基类是类模板时,需要指定一下类域,否则编译报错(如下图所示)

因为Stack<int>在实例化时,也实例化了vector<int>,但是模板是按需实例化,push_back成员函数并未实例化,所以编译器找不到。

正确代码如下:

#include 
#include 
namespace bit
{
	template
	class Stack : public std::vector
	{
	public:
		void push(const T& x)
		{
			vector::push_back(x);
		}
	};
}
int main()
{
	bit::Stack st;
	st.push(1);
    st.push(2);
    st.push(3);
	return 0;
}

二、基类与派生类之间的转换

通常情况下,我们把一个类型的对象赋值给另一个类型的指针或者引用时,存在类型转换,中间会产生临时对象,所以需要加const。而public继承中,就是一个特殊的例外,派生类对象可以赋值给基类的指针 / 基类的引用,并且不需要加const。这里的指针和引用绑定的是派生类对象中的基类部分,如下图所示:

派生类对象可以赋值给基类对象,是通过基类的拷贝构造函数或者赋值重载函数完成的。这个过程就像是派生类自己定义部分成员切掉了一样,所以也被叫做切割或者切片。但是基类对象不能赋值给派生类对象。

三、继承中的作用域

在继承体系中,基类和派生类都有独立的作用域。因此,派生类和基类中是会出现同名成员的,而派生类会屏蔽基类对同名成员的直接访问,这种情况叫隐藏(在派生类成员函数中,可以使用 基类::基类成员 显示访问)。在实际中,继承体系里面最好不要定义同名成员。

注意:如果是成员函数的隐藏,

posted on 2025-10-31 09:58  wgwyanfs  阅读(2)  评论(0)    收藏  举报

导航