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

如何让父类指针调用子类的模板成员函数getDataPtr?

解决父类指针调用子类模板成员函数的问题

原代码里,因为C++不支持模板成员函数作为虚函数,所以通过父类指针p1调用getDataPtr<Data_X>()时,只会触发父类的模板函数,没法动态调用子类的版本。要实现预期效果,得借助非模板的虚函数作为调度层,具体修改如下:

修改步骤

  • 在父类parent中定义一个非模板的虚函数,作为底层的指针返回接口,负责实际的动态绑定。
  • 改造父类的模板getDataPtr<T>(),让它调用这个虚函数并完成类型转换。
  • 子类child1重写父类的虚函数,返回自身的成员指针。
  • 给父类添加虚析构函数,避免用父类指针管理子类对象时出现内存泄漏。

修改后的完整代码

#include <iostream>
#include <memory>

class Data_X {
public:
  Data_X(int x): x(x) {}
  int getData() {
    return x;
  }
private:
  int x;
};

class parent {
public:
  // 定义纯虚的非模板函数,作为动态绑定的核心接口
  virtual void* getRawDataPtr() = 0;

  template <typename T>
  T* getDataPtr() {
    // 调用虚函数并转换为目标类型
    return static_cast<T*>(getRawDataPtr());
  }

  // 虚析构,确保子类资源能被正确释放
  virtual ~parent() = default;
};

class child1 : public parent {
public:
  child1(int x) : datax(new Data_X(x)) {}

  // 重写父类的虚函数,返回自身的成员指针
  void* getRawDataPtr() override {
    return datax;
  }

  ~child1() {
    delete datax;
  }
private:
  Data_X *datax;
};

int main() {
  std::unique_ptr<parent> p1 = std::make_unique<child1>(1);
  Data_X* dataPtr = p1->getDataPtr<Data_X>();

  std::cout << dataPtr->getData() << std::endl; // 输出1
  return 0;
}

关键修改说明

  1. 虚函数调度层:父类的getRawDataPtr()是纯虚函数,子类必须重写它。通过父类指针调用时,会动态绑定到子类的实现,拿到正确的成员指针。
  2. 模板函数做类型转换:父类的getDataPtr<T>()只是负责将虚函数返回的void*转换为目标类型T*,不需要再实现具体的指针返回逻辑。
  3. 虚析构函数:因为使用了std::unique_ptr<parent>管理child1对象,父类必须有虚析构才能触发子类的析构函数,避免内存泄漏。
  4. 子类模板函数可删除:现在父类的模板函数已经能完成类型转换工作,子类不需要再重复实现模板版本的getDataPtr()。

内容的提问来源于stack exchange,提问作者chandu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 18:05:56