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

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

相关推荐
于小猿Sup8 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶
小小编程路10 小时前
C++ 多线程与并发
java·jvm·c++
程序leo源11 小时前
Qt窗口详解
开发语言·数据库·c++·qt·青少年编程·c#
zh_xuan12 小时前
解决VS Code 控制台中文乱码
c++·vscode·乱码
郭涤生12 小时前
飞凌 RK3588 开发板同显 / 异显模式切换
c++·rk3588
计算机安禾12 小时前
【c++面向对象编程】第38篇:设计原则(二):里氏替换、接口隔离与依赖倒置
开发语言·c++
code_whiter13 小时前
C++1进阶(继承)
开发语言·c++
智者知已应修善业13 小时前
【51单片机LED闪烁10次数码管显示0-9】2023-12-14
c++·经验分享·笔记·算法·51单片机
智者知已应修善业13 小时前
【51单片机2按键控制1个敞亮LED灯闪烁和熄灭】2023-11-3
c++·经验分享·笔记·算法·51单片机
咩咦14 小时前
C++学习笔记20:日期类比较运算符重载
c++·学习笔记·类和对象·运算符重载·比较运算符·日期类