【C++】面向对象编程(四)派生类

派生类

由两部分构成:

  1. 基类构成的子对象;
  2. 派生类的部分。
cpp 复制代码
#include"num_sequence.h"//基类的定义必须已经存在

class Fibonnacci : public num_sequence{
public:
	//...
};
  • 必须为从基类继承而来的每个纯虚函数提供对应的实现;
  • 必须声明自己类的专属成员
cpp 复制代码
class Fibonacci: public num_sequence{
public:
	Fibonnacci(int len=1, int beg_pos=1):_length(len), _beg_pos(beg_pos){}
	
	virtual int elem(int pos) const;
	virtual const char* what_am_i()const{return "Fibonacci";}
	virtual ostream& print(ostream &os=cout) const;
	int length() const{return _length;}
	int beg_pos() const {return _beg_pos;}

protected:
	virtual void gen_elems(int pos) const;
	int _length;
	int _beg_pos;
	static vector<int> _elems;

通过基类的接口无法访问length()和beg_pos():

cpp 复制代码
num_sequence *ps=new ...;//举例
ps->what_am_i();//ok:通过虚函数机制,调用Fibonacci::what_am_i();
ps->max_elems();//ok:调用继承而来的num_sequence::max_elems();
ps->length();//错误:length()并非基类提供的接口中的一员;
delete ps;//ok:通过虚函数机制调用Fibonacci的析构函数。

解决:

cpp 复制代码
//在基类num_sequence加上两个纯虚函数
//length()和beg_pos()自动成为虚函数(无需关键字virtual)
virtual int length()  const = 0;
virtual int beg_pos() const = 0; 
  • 派生类的虚函数必须精确吻合基类中的函数原型;
  • 在类之外对虚函数进行定义时,不必指明关键字virtual;
  • 从基类继承而来的public成员和protected成员,都可被视为派生类自身拥有的成员,同样遵循访问层级的原则:
  • public:开放给派生类的用户使用;
  • protected:只能给后续饿顶派生类使用,无法给目前这个派生类使用;
  • private:完全无法让派生类使用。
  • 跳过虚函数机制:用类作用域运算符指明调用对象(在编译时即解析,不必等到程序运行时解析);
cpp 复制代码
int Fibonacci::elem(int pos)const
{
	if(!check_integrity(pos,_elems.size() ))
		return 0;
	
	if(pos>_elems.size())
		Fibonacci::gen_elems(pos);
	
	return _elems[ pos-1 ];
} 
  • 每当派生类有某个成员和其基类的成员同名,便会掩盖住基类的那份成员,前提是在派生类里声明了该同名成员;
  • 如果要在派生类内使用继承来的成员,必须利用类作用域运算符加以限定:
cpp 复制代码
class Fibonacci: public num_sequence{
//...
protected:
	bool check_integrity(int pos)const;
	//...
};

int Fibonacci::elem(int pos)const
{
	if(!check_integrity(pos))
		return 0;
	//...
}

inline bool Fibonacci::check_integrity(int pos)const
{
	if(!num_sequence::check_integrity(pos))
		return false;
	
	if(pos>_elems.size())
		Fibonacci:gen_elems(pos);
	
	return true;
}

在基类中,check_integrity()并未被视为虚函数,用基类指针/引用调用,解析出来的都是基类的那一份:

解决:

重新定义check_integrity(),令它拥有两个参数:(派生类的成员函数不改变)

cpp 复制代码
bool num_sequence::check_integrity(int pos, int size)
{
		if( pos <= 0 || pos > _max_elems )
		{
			//和之前相同
		}
		
		if (pos > size )
			//gen_elems()是通过虚拟机制调用
			gen_elems( pos );
			
	return true;
}
相关推荐
草莓熊Lotso3 小时前
Python 进阶核心:字典 / 文件操作 + 上下文管理器实战指南
数据结构·c++·人工智能·经验分享·笔记·git·python
Tony Bai10 小时前
高并发后端:坚守 Go,还是拥抱 Rust?
开发语言·后端·golang·rust
li星野10 小时前
打工人日报#20251231
笔记
孙严Pay10 小时前
分享三种不同的支付体验,各自有着不同的特点与适用场景。
笔记·科技·计算机网络·其他·微信
wjs202410 小时前
Swift 类型转换
开发语言
秃了也弱了。11 小时前
python实现定时任务:schedule库、APScheduler库
开发语言·python
YJlio11 小时前
VolumeID 学习笔记(13.10):卷序列号修改与资产标识管理实战
windows·笔记·学习
weixin_4407305011 小时前
java数组整理笔记
java·开发语言·笔记
小龙11 小时前
【学习笔记】多标签交叉熵损失的原理
笔记·学习·多标签交叉熵损失
Thera77711 小时前
状态机(State Machine)详解:原理、优缺点与 C++ 实战示例
开发语言·c++