You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:34:56