C++ 基类指针vector中访问子类独有方法及多态存储相关问题
报错原因说明
你通过Currency*类型的基类指针访问子类独有的com()方法,基类的成员声明里根本不存在该方法,编译阶段就会抛出成员不存在的错误,和运行时无关。
问题1:如何访问仅属于FiatMoney子类对象的成员函数com()
通过向下类型转型实现,因为你的基类包含纯虚函数,本身是多态类型,推荐用dynamic_cast做安全转型:
vector<Currency*> Wallet; Wallet.push_back(new FiatMoney("name", "shortname", 1.0, 1.0)); // 尝试将基类指针转为FiatMoney类型指针 if (FiatMoney* fiat_ptr = dynamic_cast<FiatMoney*>(Wallet[0])) { // 转型成功,说明当前对象确实是FiatMoney类型,可以调用com() fiat_ptr->com(); }
dynamic_cast会在运行时检查类型是否匹配,如果不匹配会返回空指针,通过非空判断可以避免非法访问。如果你100%确认当前指针指向的就是FiatMoney对象,也可以用static_cast做转型,性能更高但没有运行时检查,转型错误会触发未定义行为。
问题2:可以不在Currency基类中声明为virtual虚函数,直接在FiatMoney子类中定义com()方法吗
可以。如果com()是FiatMoney独有的方法,其他子类(比如Crypto)不需要实现该方法,那么完全不需要在基类中声明,否则会违反接口隔离原则,给不需要该方法的子类强加不必要的接口约束。唯一的限制就是你不能直接通过基类指针调用该方法,必须先转型为对应子类指针再调用。
问题3:上述存储不同子类对象的方式是否是规范的实现方式
存储多态对象到基类指针容器是C++的标准实现方案,但你的现有代码有两处不符合规范的问题:
- 基类缺少虚析构函数:你当前通过基类指针销毁子类对象时,只会调用基类的析构函数,子类的资源不会被释放,会产生内存泄漏。需要在Currency类的public区域添加虚析构函数:
class Currency { public: virtual ~Currency() = default; // 其余原有成员不变 };
- 不推荐使用裸指针管理动态内存:手动new出来的对象如果忘记delete会直接产生内存泄漏,推荐用智能指针代替裸指针,容器声明改为:
#include <memory> #include <vector> std::vector<std::unique_ptr<Currency>> Wallet; // 添加对象的方式改为 Wallet.push_back(std::make_unique<FiatMoney>("name", "shortname", 1.0, 1.0));
智能指针会自动在对象生命周期结束时释放内存,不需要手动管理。
内容的提问来源于stack exchange,提问作者Daniel Jankowski
相关产品推荐
相关产品推荐

