【发布时间】:2016-06-27 11:58:21
【问题描述】:
抱歉,问题很长,但需要一些上下文。我有一些代码似乎对我正在从事的项目很有用:
class Foo
{
public:
Foo( int bar = 1 );
~Foo();
typedef std::shared_ptr< Foo > pointer_type;
static pointer_type make( int bar = 1 )
{
return std::make_shared< Foo >( bar );
}
...
}
如您所见,它提供了一种将任何类构造为 PointerType 的简单方法,该类型将 shared_ptr 封装到该类型:
auto oneFoo = Foo::make( 2 );
因此,您无需在整个代码库中都引用 make_shared 和 shared_ptr 即可获得 shared_ptr 的优势。
在类中封装智能指针类型有几个优点:
- 它可以让您控制指针类型的可复制性和可移动性。
- 它对调用者隐藏了 shared_ptr 的详细信息,因此可以在 Instance() 调用中放置非平凡的对象构造,例如那些引发异常的构造。
- 在处理使用多个智能指针实现的项目时,您可以更改基础智能指针类型。您可以切换到 unique_ptr 甚至切换到特定类的原始指针,并且调用代码将保持不变。
- 它将有关(智能)指针构造和别名的详细信息集中在最了解如何操作的类中。
- 它可以让您决定哪些类可以使用智能指针以及哪些类必须在堆栈上构建。 PointerType 字段的存在向调用者提供了关于可以创建哪些类型的指针与类对应的提示。如果没有为一个类定义 PointerType,这将表明不能创建指向该类的指针;因此,必须在堆栈上以 RAII 样式创建该特定类。
但是,如果不直接键入必需的 typedef 和静态 PointerType Instance() 函数,我看不到将这段代码应用到我项目中的所有类的明显方法。我怀疑应该有一些一致的、C++11 标准的、跨平台的方式来使用基于策略的模板来执行此操作,但是一些实验并没有找到一种明显的方式来将它简单地应用于一个类中的一堆类在所有现代 C++ 编译器上都能干净地编译的方式。
你能想出一种优雅的方式来将这些概念添加到一堆类中,而不需要大量的剪切和粘贴吗?一个理想的解决方案将在概念上限制可以为哪些类型的类创建哪些类型的指针(一个类使用 shared_ptr 而另一个使用原始指针),并且它还将通过其自己的首选方法处理任何受支持类型的实例化。这样的解决方案甚至可以通过在编译时适当地在非标准和标准智能指针类型和哑指针类型之间失败来处理和/或限制强制。
【问题讨论】:
-
TBH 我不认为你正在做的工作比直接使用
std::make_shared少。 -
如果你想要指向 this 的弱指针,你可能需要考虑从 std::enable_shared_from_this 派生。
-
除非您使用
shared_from_this,否则工厂实际上应该返回std::unique_ptr,因为返回的指针是指向特定对象的唯一指针。从unique_ptr得到shared_ptr很容易,而反过来则完全不可能。 -
@Ben,如果我可以点赞评论,我会的。不要混合指向同一个对象的唯一指针和共享指针。工厂可以返回一个 shared_ptr。共享意味着多于一件事物可能指向对象,而不是多于一件事物必须指向它。
-
@RobL 我认为他的意思是
std::unique_ptr可以移动到std::shared_ptr,从而转移所有权。由于显而易见的原因,反过来是不可能的。
标签: c++ templates c++11 shared-ptr smart-pointers