【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;
}
相关推荐
祉猷并茂,雯华若锦几秒前
Appium 3.x 实战:元素定位与常见错误解析
开发语言·python·appium
Lethehong14 分钟前
飞算Java:从需求梳理到风险闭环,搭建云盾企业信息安全与权限管理平台
java·开发语言
旖-旎18 分钟前
《LeetCode 416 分割等和子集》
c++·算法·leetcode·动态规划·背包问题
爱喝水的鱼丶26 分钟前
SAP-ABAP:ALV数据导出增强——实现Excel/PDF/CSV多格式自定义导出
开发语言·性能优化·sap·abap·erp
Mortalbreeze35 分钟前
深入理解 Linux 线程机制(四):线程同步——条件变量与信号量
linux·运维·服务器·开发语言·c++
不会c+39 分钟前
C语言:入门到精通(408考研版)系列七 派生的数据类型
c语言·开发语言
Z5998178411 小时前
c#软件开发学习笔记--分组、游标与临时表、分页
笔记·学习·c#
不定积分要+C_yyy1 小时前
Java基础核心精讲:基本数据类型与包装类区别、自动装箱拆箱与缓存陷阱实战解析
java·开发语言
xingxiliang1 小时前
ReliableAgent:类似工程级可用的agent示例
java·开发语言·agent
buhuizhiyuci2 小时前
【python篇——一周速通python语法】python的基础语法操作
开发语言·python