C++中未知派生对象类型时,如何存储指针并调用成员函数?
正确解决方案:使用基类指针而非
void* 你的需求正好是C++多态机制的典型应用场景,完全不需要用不安全的void*,直接用基类指针就能实现类型安全的多态调用:
修改后的代码如下:
#include <iostream> struct rec { A* obj; // 将void*替换为基类A的指针 } myvar; class A { public: // 调整访问权限,确保外部可调用成员 void add() { myvar.obj = this; } virtual void foo() = 0; // 声明为纯虚函数,强制派生类实现 }; class B : public A { public: void foo() override { // 用override明确标记虚函数重写 std::cout << "B::foo() called\n"; } }; class C : public A { public: void foo() override { std::cout << "C::foo() called\n"; } }; int main() { C c; c.add(); myvar.obj->foo(); // 自动调用C类的foo(),多态生效 return 0; }
关键要点:
- 用基类
A*替代void*,既保证类型安全,又能借助多态自动调用派生类的成员函数 - 基类的
foo()设为纯虚函数(=0),确保所有派生类都必须实现该函数,避免空调用 - 调整成员和类的访问权限(如
public),保证外部代码能正常调用 - 派生类重写虚函数时用
override关键字,避免因拼写错误意外创建新函数
类模板封装方案(可选)
如果需要一个通用的、可复用的指针存储容器,可以用类模板封装,适配不同基类场景:
#include <iostream> template<typename Base> class ObjectHolder { private: Base* obj_ptr = nullptr; public: void store(Base* obj) { obj_ptr = obj; } void call_foo() { if (obj_ptr != nullptr) { obj_ptr->foo(); } } }; // 基类与派生类定义 class A { public: virtual void foo() = 0; }; class B : public A { public: void foo() override { std::cout << "B::foo() called\n"; } }; class C : public A { public: void foo() override { std::cout << "C::foo() called\n"; } }; int main() { ObjectHolder<A> holder; C c; holder.store(&c); holder.call_foo(); // 调用C::foo() return 0; }
这个模板类ObjectHolder可以复用在任意带foo()虚函数的基类场景中,统一管理对象指针并调用成员函数。
内容的提问来源于stack exchange,提问作者Yong Lee
相关产品推荐
相关产品推荐

