我应该使用shared_ptr <object> myObject =(shared_ptr <object>)new Object()来访问私有构造函数吗?

时间:2017-06-13 16:32:23

标签: c++ c++11 constructor shared-ptr

我正在使用代码库,该代码库广泛使用以下语法:

shared_ptr<Object> myObject = (shared_ptr<Object>) new Object();

我注意到我无法使用make_shared访问私有构造函数,但shared_ptr<Object> myObject = (shared_ptr<Object>) new Object();工作得很好。我应该只是因为它似乎有效吗?有危险吗?它与make_shared有什么不同?

我知道this问题中的答案,该问题对make_shared和:

进行了比较
std::shared_ptr<Object> p2(new Object("foo"));

但我还没有找到我遇到的语法的参考。它是不同的,还是与上面相同?

1 个答案:

答案 0 :(得分:10)

make_shared在与控制块相同的内存块中分配对象。这样可以提高缓存一致性并减少分配。

允许make_shared执行此操作的一种方法是在您的类中使用私有令牌,以及使用该令牌的公共构造函数

class Object {
private:
  struct token_t{ private: token_t() {}; friend class Object; };
  static token_t token() { return {}; }
  Object() = default;
public:
  Object( token_t ):Object() {}
};

现在我们可以make_shared<Object>( Object::token() )

这给了我们一个分配,并没有违反构造的隐私,因为只有访问Object私有字段的东西才能调用该构造函数。但是,它们可以将令牌传递给另一个函数(如make_shared),然后它可以调用相关的构造函数。这自然适用于更多的论据。

至于你的语法:

std::shared_ptr<Object> myObject = (std::shared_ptr<Object>) new Object();

(std::shared_ptr<Object>) new Object();只是从shared_ptr<Object>明确构建new Object()。它相当于std::shared_ptr<Object>(new Object)

然后我们接受这个prvalue并从中构造myObject。在C ++ 03 11和14中,这种复制/移动结构被省略了。在C ++ 17中,prvalue&#34;构造指令&#34;直接应用于myObject。在实践中,这导致相同的机器代码(除非你是一个傻瓜,并明确告诉你的编译器不要忽视构造)。

简而言之,它有效。唯一的缺点是从Object分配中重复分配单独的控制块。