【和春笋一起学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;

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

相关推荐
白杨尚青7 小时前
C++进阶篇(二):多态——虚函数、重写、虚函数表与三个经典坑(附完整代码仓库)
开发语言·c++·多态·虚函数·重写·动态绑定
syagain_zsx7 小时前
spdlog实战:日志分级、滚动与性能调优
linux·c++·日志库·二次开发日志库
weixin_307779131 天前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
AI wins1 天前
c++新增頭文件
c++
Shadow(⊙o⊙)1 天前
仿muduo实现高并发服务器——事件就绪管理Channel.hpp
服务器·c++
by209991 天前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表
音草1 天前
C++ 继承详解:从概念到菱形继承
c++
weixin_307779131 天前
C++代码实现MATLAB中的spectralcluster函数功能
开发语言·c++·算法·matlab
xiaoye-duck1 天前
《C++ 项目:手写大模型接入 SDK》Trae IDE 开发环境搭建与依赖管理
c++·ide·语言模型
沫璃染墨1 天前
《Qt从零入门系列(十四):QThread多线程详解——从线程创建到客户端阻塞处理》
开发语言·c++·笔记·qt·ui·交互·线程