gpt4 book ai didi

C++11 make_shared 实例化

转载 作者:可可西里 更新时间:2023-11-01 18:18:24 31 4
gpt4 key购买 nike

很抱歉这个问题太长了,但一些上下文是必要的。我有一些代码似乎对我正在从事的项目很有用:

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 的优势。

在类中封装智能指针类型有几个优点:

  1. 它让您可以控制指针类型的可复制性和可移动性。
  2. 它向调用者隐藏了 shared_ptr 的详细信息,因此可以在 Instance() 调用中放置重要的对象构造,例如那些抛出异常的构造。
  3. 在处理使用多个智能指针实现的项目时,您可以更改底层智能指针类型。您可以切换到 unique_ptr 或什至切换到特定类的原始指针,调用代码将保持不变。
  4. 它将有关(智能)指针构造和别名的详细信息集中在最了解如何操作的类中。
  5. 它让您决定哪些类可以使用智能指针以及哪些类必须在堆栈上构建。 PointerType 字段的存在向调用者提供了有关可以创建与该类对应的指针类型的提示。如果没有为类定义 PointerType,则表明不能创建指向该类的指针;因此,必须在堆栈上创建该特定类,RAII 样式。

但是,如果不直接键入必需的 typedef 和静态 PointerType Instance() 函数,我看不出有什么明显的方法可以将这段代码应用于我项目中的所有类。我怀疑应该有一些一致的、C++11 标准的、跨平台的方法来使用基于策略的模板来做到这一点,但是一些实验还没有找到一种明显的方法来将这个平凡地应用到一个类中的一堆类中。在所有现代 C++ 编译器上进行干净编译的方式。

您能想出一种优雅的方式来将这些概念添加到一堆类中,而无需进行大量剪切和粘贴吗?一个理想的解决方案会在概念上限制可以为哪些类型的类创建哪些类型的指针(一个类使用 shared_ptr 而另一个使用原始指针),并且它还将通过其自己的首选方法处理任何受支持类型的实例化。这样的解决方案甚至可以通过在编译时适本地失败来处理和/或限制非标准和标准智能和哑指针类型之间的强制转换。

最佳答案

一种方法是使用 curiously recurring template pattern .

template<typename T>
struct shared_factory
{
using pointer_type = std::shared_ptr<T>;

template<typename... Args>
static pointer_type make(Args&&... args)
{
return std::make_shared<T>(std::forward<Args>(args)...);
}
};

struct foo : public shared_factory<foo>
{
foo(char const*, int) {}
};

我相信这会给你你想要的。

foo::pointer_type f = foo::make("hello, world", 42);

然而...

我不推荐使用这种方法。试图规定类型的用户如何实例化该类型是不必要的限制。如果他们需要一个 std::shared_ptr,他们可以创建一个。如果他们需要 std::unique_ptr,他们可以创建一个。如果他们想在堆栈上创建一个对象,他们可以。我认为强制要求如何创建和管理用户的对象不会有任何好处。

解决您的问题:

  1. It lets you control the copyability and moveability of the pointer types.

这有什么好处?

  1. It hides the shared_ptr details from callers, so that non-trivial object constructions, such as those that throw exceptions, can be placed within the Instance() call.

我不确定你在这里的意思。希望您不会捕获异常并返回 nullptr。那将是 Java 级的错误。

  1. You can change the underlying smart pointer type when you're working with projects that use multiple smart pointer implementations. You could switch to a unique_ptr or even to raw pointers for a particular class, and calling code would remain the same.

如果您正在使用多种智能指针,或许让用户根据给定情况选择合适的种类会更好。此外,我认为具有相同的调用代码但返回不同类型的句柄可能会造成混淆。

  1. It concentrates the details about (smart) pointer construction and aliasing within the class that knows most about how to do it.

一个类在什么意义上“最”了解如何进行指针构造和别名?

  1. It lets you decide which classes can use smart pointers and which classes must be constructed on the stack. The existence of the PointerType field provides a hint to callers about what types of pointers can be created that correspond for the class. If there is no PointerType defined for a class, this would indicate that no pointers to that class may be created; therefore that particular class must be created on the stack, RAII style.

同样,我从根本上不同意某种类型的对象必须以某种方式创建和管理的想法。这是 singleton pattern 的原因之一。太阴险了。

关于C++11 make_shared 实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35953783/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com