我应该使用 shared_ptr<Object> myObject = (shared_ptr<Object>) new Object() 来访问私有构造函数吗?
Should I use shared_ptr<Object> myObject = (shared_ptr<Object>) new Object() to access private constructors?
我正在使用广泛使用以下语法的代码库:
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"));
但我没能找到对我遇到的语法的引用。和上面的有区别吗,还是一样?
make_shared
将对象分配在与控制块相同的内存块中。这提高了缓存一致性并减少了分配。
允许 make_shared
执行此操作的一种方法是在您的 class 中拥有一个 私有令牌 ,以及一个 public 使用该令牌的构造函数。
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();
只是显式地从 new Object()
构造一个 shared_ptr<Object>
。相当于std::shared_ptr<Object>(new Object)
.
然后我们取这个纯右值并从中构造 myObject
。在 C++03 11 和 14 中,这个 copy/move 结构被省略了。在 C++17 中,纯右值 "construction instructions" 直接应用于 myObject
。实际上,这会产生相同的机器代码(除非你是个傻瓜并明确告诉你的编译器不要省略构造)。
简而言之,它有效。唯一的缺点是来自 Object
分配的独立控制块的双重分配。
我正在使用广泛使用以下语法的代码库:
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"));
但我没能找到对我遇到的语法的引用。和上面的有区别吗,还是一样?
make_shared
将对象分配在与控制块相同的内存块中。这提高了缓存一致性并减少了分配。
允许 make_shared
执行此操作的一种方法是在您的 class 中拥有一个 私有令牌 ,以及一个 public 使用该令牌的构造函数。
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();
只是显式地从 new Object()
构造一个 shared_ptr<Object>
。相当于std::shared_ptr<Object>(new Object)
.
然后我们取这个纯右值并从中构造 myObject
。在 C++03 11 和 14 中,这个 copy/move 结构被省略了。在 C++17 中,纯右值 "construction instructions" 直接应用于 myObject
。实际上,这会产生相同的机器代码(除非你是个傻瓜并明确告诉你的编译器不要省略构造)。
简而言之,它有效。唯一的缺点是来自 Object
分配的独立控制块的双重分配。