【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;
}
相关推荐
彷徨而立5 分钟前
【C/C++】多线程读写普通 int 变量的一些问题
java·c语言·c++
浪兎兎15 分钟前
Vue CLI笔记
前端·vue.js·笔记
Freak嵌入式22 分钟前
树莓派 Pico GPIO 深度解析:从 MCU 架构到寄存器控制,底层原理与实践指南
java·开发语言·科技·单片机·嵌入式硬件·架构
摇滚侠25 分钟前
《SpringBoot 3:入门与应用实战》第 9 章 使用 WebMvc 开发应用 阅读笔记 20
spring boot·笔记·后端
蒸蒸yyyyzwd26 分钟前
cpp web server 面试可能问题总结
c++·笔记·八股
啊啊啊啊啊!!!!29 分钟前
【c++】map和set的使用
开发语言·c++
hu92451955930 分钟前
Matlab保护源代码—P文件和exe文件详细解析
开发语言·matlab
for_ever_love__31 分钟前
python爬虫: GET请求与POST请求
开发语言·爬虫·python·网络编程
Freak嵌入式33 分钟前
实战对比:用 mpremote/Putty/MobaXterm 连接树莓派 Pico REPL,谁更省心?
java·大数据·开发语言·科技·单片机·嵌入式硬件
阳光宅男@李光熠35 分钟前
【电子通识】排阻和普通电阻有什么区别?
笔记·学习