【和春笋一起学C++】(五十九)派生类和基类之间的关系

目录

使用派生类

派生类和基类之间的关系


使用派生类

要使用派生类,程序首先要能够访问基类声明,所以通常将基类声明和派生类声明放在同一个头文件中(也可以把它们放在不同的头文件中,但由于这两个类是相关的,因此通常把它们放在同一个头文件中),需要注意的是,在基类和派生类声明的头文件中,基类声明必须放在派生类声明的前面,否则编译时会报无法找到基类定义的错误。同理,基类和派生类的方法定义也通常放在一个.cpp文件中。

如《类继承》文章中的Student类和CulturalStudent类。

cpp 复制代码
class Student
{
public:
	Student(string name_);
	Student(string name_, unsigned short yw, unsigned short sx, unsigned short yy);
	~Student();
	void scoreSet(int yuwen_score_, int shuxue_score_, int yingyu_score_);
	unsigned short get_yuwen_score() { return yuwen_score; }
	unsigned short get_shuxue_score() { return shuxue_score; }
	unsigned short get_yingyu_score() { return yingyu_score; }
    string get_name() { return name; }
	void show_score()
	{
		cout << "语文分数:" << yuwen_score << endl;
		cout << "数学分数:" << shuxue_score << endl;
		cout << "英语分数:" << yingyu_score << endl;
	}
private:
	std::string name;
	unsigned short yuwen_score;
	unsigned short shuxue_score;
	unsigned short yingyu_score;
};

class CulturalStudent:public Student
{
private:
	unsigned short lishi_score;
	unsigned short zhengzhi_score;
public:
	CulturalStudent(string name_, unsigned short yw, unsigned short sx, unsigned short yy,
		unsigned short ls, unsigned short zz);
	CulturalStudent(const Student& st, unsigned short ls, unsigned short zz);
	unsigned short get_lishi_score() { return lishi_score; }
	unsigned short get_zhengzhi_score() { return zhengzhi_score; }
    void show_name_and_score(Student& st);

};

派生类和基类之间的关系

  • 对于公有派生,派生类对象可以使用基类的方法。

例如:

cpp 复制代码
CulturalStudent st1("xiaoming", 82, 82, 84, 90, 91);
st1.get_shuxue_score();
  • 基类指针可以在不进行显式类型转换的情况下指向派生类对象;基类引用可以在不进行显式类型转换的情况下引用派生类对象。

例如:

cpp 复制代码
CulturalStudent st1("xiaoming", 82, 82, 84, 90, 91);
Student *st2 = &st1;
Student &st3 = st1;
st2->get_shuxue_score();
st3.get_shuxue_score();

通常,C++要求引用和指针类型与被赋给的类型匹配,但这一规则对继承来说是例外。不过,这种例外是单向的,不可以将基类对象和地址赋给派生类引用和指针。

基于这个规则,使用基类引用作为形参的函数可以用基类对象或派生类对象作为实参。

cpp 复制代码
void CulturalStudent::show_name_and_score(Student& st)
{
	cout << "name:" << st.get_name();
	cout << "  shuxue:" << st.get_shuxue_score();
}

上面的函数中,函数参数是基类引用,它可以指向基类对象或派生类对象,所以实参可以使用Student类对象或CulturalStudent类对象。以下调用都是可以的:

cpp 复制代码
    CulturalStudent st1("xiaoming", 82, 82, 84, 90, 91);
	Student *st2 = &st1;
	st1.show_name_and_score(*st2);
	st1.show_name_and_score(st1);

同理,对于形参为指向基类的指针的函数,也存在类似的关系,可以使用基类对象的地址或派生类对象的地址作为实参。

**引用兼容性属性也能够将基类对象初始化为派生类对象。**如:

cpp 复制代码
CulturalStudent st1("xiaoming", 82, 82, 84, 90, 91);
Student st5(st1);

初始化st5的过程如下:

Student st5(st1)匹配的构造函数原型为:Student(const CulturalStudent&),Student类中没有这样的构造函数,但存在隐式复制构造函数:Student(const Student&),形参是基类引用,因此可以引用派生类对象。将t5初始化为t1时,将复制t1对象中的name,yuwen_score,shuxue_score, yingyu_score成员值。具体的说,t5被初始化为嵌套在t1对象中的Student对象。

同样,也可以将派生类对象赋给基类对象,如下:

cpp 复制代码
CulturalStudent st1("xiaoming", 82, 82, 84, 90, 91);
Student st5("xiaohong", 90, 89, 78);
st5 = st1;

此时,程序将调用基类的隐式重载赋值操作符函数:

cpp 复制代码
Student& operator=(const Student&)const;

重载赋值操作符函数的形参是基类引用,因此,可以将派生类对象作为实参赋给它。

相关推荐
码匠许师傅2 分钟前
【C++三方组件】glog:Google 出品的 C++ 日志库
c++
Lazionr10 分钟前
二叉搜索树:从树形结构到高效查找
开发语言·c++
此生决int12 分钟前
深入理解C++系列(21)——异常
开发语言·c++
曼巴UE514 分钟前
UE5 客户端 需要的网络同步概念总结(3 )-事件同步 RPC 以及三种调用方式
网络·c++·网络协议·学习·rpc·ue5
All for pursuit.26 分钟前
【栈-5】84.柱状图中最大的矩形
数据结构·c++·算法·leetcode
01二进制代码漫游日记31 分钟前
C++之类和对象(上)02
c++
渡我白衣1 小时前
HttpRequest与HttpResponse的实现
服务器·数据结构·c++·人工智能·tcp/ip·机器学习·caffe
刃神太酷啦1 小时前
前端入门第一课:HTML 基础语法 + 常用标签 + 实战全解
服务器·c语言·前端·javascript·css·c++·html
蒸蒸yyyyzwd1 小时前
八股学习笔记 day42
c++·八股
凤年徐1 小时前
C++ 仿 muduo 高并发服务器:用户态缓冲区 Buffer 模块实现
linux·c++