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

C++基类数组存储子类实例时如何调用继承类draw方法

问题根因

你的代码跑不通有三个核心问题:

  1. 对象切片:数组元素类型是基类Panel,存入派生类实例时,派生类独有的成员(虚表、子类方法、自定义成员)会被直接截断,数组里存储的是纯基类对象,和原来的子类实例没有关系。
  2. 多态未生效:基类没有定义draw虚函数,编译器编译阶段就会尝试在Panel类里找draw方法,找不到必然报错。
  3. 隐式编译错误:两个子类的构造函数没有加public修饰,class默认访问权限是私有,外部根本无法构造子类实例。
修正实现

第一步:改造基类,启用多态

基类定义纯虚draw方法,同时加虚析构保证多态场景下资源释放正确:

class Panel
{
public:
  const char* name;
  int id;
  Panel(const char* name, int id) : name(name), id(id) { }
  // 纯虚函数,所有子类必须实现draw逻辑
  virtual void draw() = 0;
  // 虚析构,避免基类指针释放子类对象时内存泄漏
  virtual ~Panel() = default;
};

第二步:子类重写draw方法

子类重写虚函数时加override关键字,编译器会自动校验重写签名是否正确,避免写错参数、const属性导致重写失效,同时把构造函数设为公有:

class SpecialPanel1 : public Panel
{
public:
  SpecialPanel1(const char* name, int id) : Panel(name, id) { }
  void draw() override
  {
    // 面板1绘制逻辑
  }
};

class SpecialPanel2 : public Panel
{
public:
  SpecialPanel2(const char* name, int id) : Panel(name, id) { }
  void draw() override
  {
    // 面板2绘制逻辑
  }
};

第三步:数组存储基类指针,避免对象切片

不要直接存基类对象,存基类指针(推荐用智能指针自动管理内存,避免手动new/delete的泄漏问题):

#include <memory>

int main()
{
  int visiblePanel_id = 1;

  // 存基类智能指针的数组,不会触发对象切片
  std::unique_ptr<Panel> panels[2] = {
    std::make_unique<SpecialPanel1>("", 1),
    std::make_unique<SpecialPanel2>("", 2),
  };

  // 遍历用右值引用接收,避免不必要的拷贝
  for (auto&& p : panels) {
    if (p->id == visiblePanel_id) {
      p->draw();
      break; // 找到目标面板直接退出循环,不用遍历剩余项
    }
  }

  return 0;
}
可选优化

如果面板数量较多,每次遍历数组找ID效率太低,可以改用哈希表存ID到面板的映射,查找时间复杂度从O(n)降到O(1):

#include <unordered_map>
#include <memory>

int main()
{
  int visiblePanel_id = 1;
  std::unordered_map<int, std::unique_ptr<Panel>> panel_map;
  panel_map.emplace(1, std::make_unique<SpecialPanel1>("", 1));
  panel_map.emplace(2, std::make_unique<SpecialPanel2>("", 2));

  // 直接根据ID查找面板,无需遍历
  if (auto it = panel_map.find(visiblePanel_id); it != panel_map.end()) {
    it->second->draw();
  }

  return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:51:07