基类指针能指向派生类对象,因派生类内存布局包含基类子对象,满足is-a关系;通过虚函数表实现动态绑定,调用时根据对象实际类型执行对应函数,从而实现多态;但基类指针仅能访问基类成员,需向下转型访问派生类特有成员,且基类析构函数应声明为virtual以确保正确析构。

在C++中,基类指针可以指向派生类对象,这是实现多态的重要基础。理解其原理有助于掌握面向对象编程中的动态绑定机制。
基类指针为何能指向派生类对象
当一个派生类继承自基类时,派生类对象的内存布局中包含了基类的子对象。也就是说,派生类对象的起始部分与基类对象的内存结构一致。因此,基类指针可以通过指向派生类对象的起始地址来“看到”其中的基类部分。
这种赋值是安全的,因为派生类“是一个”基类(is-a关系),符合类型兼容性规则。
例如:class Base { public: int a; };class Derived : public Base { public: int b; };Derived d;Base* ptr = &d; // 合法,ptr指向d中的Base部分
立即学习“C++免费学习笔记(深入)”;
虚函数与动态绑定的关键作用
如果基类中定义了虚函数,那么通过基类指针调用该函数时,实际执行的是派生类中重写的版本。这依赖于虚函数表(vtable)和虚表指针(vptr)机制。
每个带有虚函数的类都有一个虚函数表,存储着该类虚函数的实际地址。对象在创建时会包含一个指向该表的指针。
媒体包提供了可管理各种媒体类型的类。这些类可提供用于执行音频和视频操作。除了基本操作之外,还可提供铃声管理、脸部识别以及音频路由控制。本文说明了音频和视频操作。 本文旨在针对希望简单了解Android编程的初学者而设计。本文将指导你逐步开发使用媒体(音频和视频)的应用程序。本文假定你已安装了可开发应用程序的Android和必要的工具,同时还假定你已熟悉Java或掌握面向对象的编程概念。感兴趣的朋友可以过来看看
- 基类指针虽然类型是基类,但它指向的是派生类对象
- 调用虚函数时,程序通过对象的vptr找到派生类的vtable
- 最终调用的是派生类中重写后的函数实现
这就是运行时多态的核心机制。
基类指针访问成员的限制
基类指针只能访问基类中定义的成员(包括public和protected成员),即使它指向的是派生类对象。
- 不能直接通过基类指针访问派生类特有的成员变量或方法
- 若需访问派生类特有成员,必须进行向下转型(如使用
static_cast或dynamic_cast) - 向下转型存在风险,应确保指针实际指向的是目标派生类型
析构函数必须为虚函数的原因
当通过基类指针删除派生类对象时,如果基类的析构函数不是虚函数,只会调用基类的析构函数,导致派生类部分未被清理,造成资源泄漏。
将基类析构函数声明为virtual后,delete操作会触发正确的析构顺序:先调用派生类析构函数,再调用基类析构函数。
class Base {public: virtual ~Base() {}};
基本上就这些。基类指针指向派生类对象的本质是内存布局兼容性和虚函数机制共同作用的结果,合理使用可实现灵活的多态设计,但要注意类型安全和资源管理问题。










