工厂方法结合共享指针与受限构造函数的问题求助
问题分析与解决方案
你的代码有两个核心问题导致了运行时错误,同时也无法实现动态调用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
相关产品推荐
相关产品推荐

