C++程序设计POJ》《WEEK6 多态与虚函数》《多态的实现原理》《虚函数表》
“多态”的关键在于通过基类指针或引用调用
一个虚函数时,编译时不确定到底调用的是基类还
是派生类的函数,运行时才确定---- 这叫“动态
联编”。“动态联编” 底是怎么实现的呢?
#include<iostream> using namespace std; class Base { public: int i; virtual void Print() { cout << "base:print"; } }; class Derived :public Base { public: int n; virtual void Print() { cout << "drived:print" << endl; } }; int main() { Derived d; cout << sizeof(Base) << "," << sizeof(Derived); while (1); return 0; } // 程序运行输出结果: 8, 12 // 为什么都多了4个字节?
多态实现的关键--- 虚函数表
每一个有虚函数的类(或有虚函数的类的派生类)
都有一个虚函数表,该类的任何对象中都放着虚函数
表的指针。虚函数表中列出了该类的虚函数地址。多
出来的4个字节就是用来放虚函数表的地址的。
#include<iostream> using namespace std; class A { public: virtual void Func() { cout << "A::FUNC" << endl; } }; class B :public A { public: virtual void Func() { cout << "B::func" << endl; } }; int main() { A a; A *pa = new B(); //64位程序指针为8字节 long long * p1 = (long long *)&a; long long * p2 = (long long *)pa; *p2 = *p1; // 更改虚函数表的内容 pa->Func(); while (1); return 0; } // B::Func // A::Func
虚析构函数
只要基类是虚析构函数,那么派生类默认都是虚析构函数
虚析构函数通过基类指针删除掉派生类对象
通过基类的指针删除派生类对象时,通常情况下只调用基类的析构
函数
但是,删除一个派生类的对象时,应该先调用派生类的析构函
数,然后调用基类的析构函数。
解决办法:把基类的 析构函数声明为 virtual
派生类的析构函数可以 virtual 不进行声明
通过基类的指针删除派生类对象时,首先调用派生类的析构函
数,然后调用基类的析构函数
一般来说,一个类如果定义了虚函数,则应该将析构函数也定义成
虚函数。或者,一个类打算作为基类使用,也应该将析构函数定义
成虚函数。
注意: 不允许以虚函数作为构造函数
纯虚函数和抽象类
纯虚函数: 没有函数体的虚函数
class A {
private: int a;
public:
virtual void Print( ) = 0 ;// 纯虚函数
void fun() { cout << "fun"; }
};
包含纯虚函数的类叫抽象类
抽象类只能作为基类来派生新类使用,不能创建抽象类的对象
抽象类的指针和引用可以指向由抽象类派生出来的类的对象
A a ;
// 错, A 是抽象类,不能创建对象
A * pa ;
// 可以定义抽象类的指针和引用
pa = new A ;
错误 , A 是抽象类,不能创建对象
在抽象类的成员函数内可以调用纯虚函数,但是在构造函数或析构函数内部
不能调用纯虚函数。
如果一个类从抽象类派生而来,那么当且仅当它实现了基类中的所有纯虚函
数,它才能成为非抽象类。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2018-06-24 第三章 字符串、向量和数组