工厂方法返回 shared_ptr 是为了实现自动内存管理、支持共享所有权和多态性,避免内存泄漏并提升代码安全性与灵活性;通过 std::make_shared 创建对象可提高性能和异常安全性,适用于多模块共享对象或生命周期不确定的场景,尤其在需要将对象存入容器或传递给回调时比 unique_ptr 更合适,但需注意避免循环引用并保证注册机制的线程安全,是现代 c++++ 中构建可扩展系统的推荐做法。

在 C++ 的工厂模式中,使用智能指针(尤其是
std::shared_ptr)作为返回类型是一种现代、安全且推荐的做法。相比传统的裸指针或
std::unique_ptr,返回
shared_ptr能更好地管理对象生命周期,避免内存泄漏,同时支持灵活的共享语义。
为什么工厂方法返回 shared_ptr
?
工厂模式的核心是将对象的创建过程封装起来,客户端无需关心具体类型,只需通过接口使用对象。返回
shared_ptr的主要优势包括:
- 自动内存管理:对象在不再被引用时自动释放,避免资源泄漏。
- 共享所有权:多个组件可以安全地共享同一个对象实例。
-
多态支持良好:
shared_ptr
可以持有派生类对象,适合多态场景。 - 与标准库和现代 C++ 代码兼容性好:比如可以轻松存入容器、传递给回调等。
工厂方法返回 shared_ptr
的典型实现
假设我们有一个图形形状的基类和几个派生类:
#include#include class Shape { public: virtual ~Shape() = default; virtual void draw() const = 0; }; class Circle : public Shape { public: void draw() const override { // 绘制圆形 } }; class Rectangle : public Shape { public: void draw() const override { // 绘制矩形 } };
接下来,我们实现一个工厂类或工厂函数,返回
std::shared_ptr:
#include
注册类型并使用:
// 注册类型
ShapeFactory::registerType("circle", []() { return std::make_shared(); });
ShapeFactory::registerType("rectangle", []() { return std::make_shared(); });
// 使用工厂创建对象
auto shape = ShapeFactory::create("circle");
if (shape) {
shape->draw();
} 何时选择 shared_ptr
而不是 unique_ptr
?
虽然
unique_ptr更轻量、性能略优,但在以下场景中,
shared_ptr是更合适的选择:
- 多个模块需要共享对象所有权。
- 对象可能被放入容器、回调、观察者列表等需要长期持有副本的地方。
- 工厂创建的对象生命周期不确定,且可能被多方引用。
如果你能确定对象只有一个所有者,且不会被共享,
unique_ptr更高效。但在通用工厂中,尤其是框架或库代码中,
shared_ptr更加灵活和安全。
注意事项与最佳实践
使用
make_shared
而不是直接new
:
它更高效(一次内存分配),也更安全(避免异常时的内存泄漏)。避免循环引用:
如果对象之间存在互相引用,注意使用weak_ptr
防止内存泄漏。注册机制可扩展:
上述工厂支持运行时注册,适合插件式架构。线程安全考虑:
如果多个线程同时调用create
,确保creators()
的访问是线程安全的(首次初始化是安全的,但注册操作需加锁)。
基本上就这些。返回
shared_ptr的工厂方法是现代 C++ 中构建可维护、可扩展系统的重要手段,尤其适用于需要多态和共享所有权的场景。










