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

工厂方法结合共享指针与受限构造函数的问题求助

问题分析与解决方案

你的代码有两个核心问题导致了运行时错误,同时也无法实现动态调用InheritedA::hello()的需求:

1. Base::hello不是虚函数

C++中要实现动态多态(根据指针的实际类型调用对应函数),必须将基类的成员函数声明为虚函数。你的Base::hello没有virtual修饰,所以调用b->hello()时会进行静态绑定,直接调用基类版本,而不是实际指向的子类版本。

2. Base::hello存在未定义行为

Base::hello的返回类型是string,但函数体是空的{},没有返回任何值。这种不符合函数返回要求的写法会触发未定义行为,这就是你遇到运行时错误的直接原因。


修复后的完整代码

#include <iostream>
#include <memory>
#include <string> // 记得包含string头文件,原代码漏了!
using namespace std;

class Base {
public:
    static shared_ptr<Base> factory();
    // 声明为虚函数,提供默认实现(或改为纯虚函数)
    virtual string hello() { return "I am Base"; };
    virtual ~Base() {};
protected:
    Base(){};
};

class InheritedA : public Base{
    friend class Base;
public:
    // 使用override明确覆盖基类虚函数,避免拼写错误
    string hello() override {return "I am iA";}
protected:
    InheritedA() {};
};

// 实现factory函数,返回InheritedA的实例
shared_ptr<Base> Base::factory() {
    // 因为InheritedA的构造是protected,Base是友元所以可以直接构造
    return make_shared<InheritedA>();
}

int main() {
    shared_ptr<Base> b = Base::factory();
    cout << b->hello() << endl; // 现在会输出"I am iA"
    return 0;
}

关键修复点说明

  • 在Base::hello前添加virtual关键字,开启动态多态支持。
  • 给Base::hello添加合理的返回值,消除未定义行为。
  • 在InheritedA::hello后添加override关键字,编译器会帮你检查是否正确覆盖了基类的虚函数(比如函数名、参数、返回值是否匹配),避免低级错误。
  • 补全了Base::factory的实现,正确返回InheritedA的shared_ptr实例。
  • 补充了<string>头文件,原代码中使用string但未包含对应头文件,这也是潜在的编译问题(有些编译器可能隐式包含,但标准中不保证)。

现在运行代码,b->hello()会根据b指向的实际InheritedA对象,动态调用InheritedA::hello(),输出I am iA,同时不会再出现运行时错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:39:04