当前位置: 首页 > news >正文

【C++】面向对象编程(六)在派生类中定义一个虚函数、虚函数的静态解析

在派生类中定义一个虚函数

  • 定义派生类时:
  1. 将基类中的虚函数覆盖掉:派生类提供新定义,所声明的函数原型必须完全符合基类所声明的函数原型(包括:参数列表、返回类型、常量性);
  2. 原封不动继承基类中的虚函数;如果继承的是纯虚函数,则这个派生类也会被视为抽象类,无法为它定义任何对象。
  • 在派生类中,如果其基类的同名成员函数已声明为虚函数,则派生类的同名成员函数声明和定义前不用加virtual,即为了覆盖基类的某个虚函数,而进行函数声明时,不一定得加上关键字virtual,编译器会自动根据两个同名函数的原型声明,决定某个函数是否会覆盖其基类中的同名函数。
class num_sequence{
public:
	virtual const char*what_am_i()const{return "num_sequence\n";}
//...
};
class Fibonacci : public num_sequence{
public:
	virtual const char* what_am_i(){return "Fibonacci\n";}
	//编译器报错:基类声明为const,派生类却是non-const
	//...
};
  • 返回类型必须完全吻合“的一个例外——当基类的虚函数返回某个基类形式(通常是指针或者引用)时,派生类中的同名函数便可以返回该基类所派生出来的类型:
class num_sequence{
public:
	//我们想让派生类的clone()函数可返回一个指针,
	//指向基类num_sequence的任何一个派生类
	virtual num_sequence *clone() = 0;
	
	//...
};

class Fibonacci : public num_seuqence{
public:
	//派生类同名函数不用加virtual
	Fibonacci *clone(){return new Fibonacci(*this);}
//...
};

虚函数的静态解析

为了能够在“单一对象中展现多种类型”,多态需要一层间接性。在C++中,唯有用基类的指针和引用才能够支持面向对象编程概念

虚函数机制无用的两种情况:

  1. 基类的构造函数和析构函数里
  2. 使用的是基类的对象,而非基类对象的指针或引用

所以,在基类的构造函数中,派生类的虚函数绝对不会被调用;基类的析构函数同理。


示例分析:

  • 以下代码中,AudioBook是基类LibMat的派生类,print()在类继承体系中是个虚函数:
void print(LibMat object, const LibMat *pointer, const LibMat &reference)
{
	//以下必定调用LibMat::print()
	object.print();
	
	//以下一定会通过虚函数机制来解析,
	//我们无法预知哪一份print()会被调用
	pointer->print();
	reference.print();
}
  • 当我们为基类声明一个实际对象(如print()的第一个参数),同时也就分配出了足以容纳该实际对象的内存空间;
  • 如果稍后传入的是个派生类对象,那就没有足够的内存放置派生类中的各个数据成员,例如我们将AudioBook对象传给print()
int main()
{
	AudioBook iWish("Her pride of 10", "Stanley Lippman", "Jeremy Irons");
	print(iWish, iWish, iWish);
	//...
}
  • 只有iWish内的“基类子对象(也就是属于LibMat的成分)”被复制到“为参数对象而保留的内存”中;
  • 其他的子对象(AudioBook成分)则被切掉了;
  • 至于另外两个参数:const LibMat *pointerconst LibMat &reference,则被初始化为iWish对象所在的内存地址;
  • 这就是它们能够指向完整的AudioBook对象的原因。

相关文章:

  • uniapp快速入门系列(2)- Vue基础知识
  • NPDP产品经理知识(产品创新管理)
  • Games104现代游戏引擎笔记高级ai
  • Linux 安全 - 内核提权
  • 动态代理IP常见超时原因及解决方法
  • 如何实现MySQL的增删改查
  • 【C++设计模式之迭代器模式】分析及示例
  • 微服务技术栈
  • 二叉搜索树的基础操作
  • PyTorch Lightning - LightningModule 训练逻辑 (training_step) 异常处理 try-except
  • Python—Scrapy实践项目
  • objective-c 基础学习
  • 软考 系统架构设计师系列知识点之软件架构风格(5)
  • 2023-2024年华为ICT网络赛道模拟题库
  • 【VUE3 Teleport】
  • redis分布式秒杀锁
  • 【数据结构】二叉树
  • 厌烦了iPhone默认的热点名称?如何更改iPhone上的热点名称
  • 视觉效果绝佳的制作电子宣传册的网站
  • C++交换a和b的方法
  • 马上评丨规范隐藏式车门把手,重申安全高于酷炫
  • “80后”赵亮出任上海普陀区委副书记
  • 虚假认定实质性重组、高估不良债权价值,原中国华融资产重庆分公司被罚180万元
  • 明明睡够了,怎么还有黑眼圈?可能是身体在求救
  • 人民日报整版聚焦:铭记二战历史,传承深厚友谊
  • 国家主席习近平同普京总统共见记者