为什么下面的代码编译
shared_ptr<parent> p(new parent);
而下面的没有
shared_ptr<parent> p2 = new parent;
是否有任何理由不允许 shared_ptr 使用“=”符号?
一般来说,如果一个指针像
int *p = new int;
应该与
int *p(new int);
不是吗?
为什么下面的代码编译
shared_ptr<parent> p(new parent);
而下面的没有
shared_ptr<parent> p2 = new parent;
是否有任何理由不允许 shared_ptr 使用“=”符号?
一般来说,如果一个指针像
int *p = new int;
应该与
int *p(new int);
不是吗?
std::shared_ptr
的“指针接收”构造函数被声明explicit
。
template< class Y >
explicit shared_ptr( Y* ptr );
这样,您就不能使用复制初始化 ( shared_ptr<parent> p2 = new parent;
)。
std::shared_ptr
我能想到为什么要创建构造函数的最好理由explicit
是,您不太可能在将原始的、不受std::shared_ptr
对象管理的对象传递给接收std::shared_ptr
.
#include <memory>
void func(std::shared_ptr<int> ptr) { /* ... */}
int main() {
auto iptr = std::make_shared<int>();
func(iptr); // OK
/*
int* iptr = new int;
func(iptr); // Unclear who would eventually manage (delete) the pointer
// ...
delete iptr; // Undefined behavior!
*/
}
如果没有制作构造函数explicit
,那么您可以执行注释掉的代码。
另外,就像@R。Martinho Fernandes建议,如果new
传递非 ed 指针,您可能会遇到问题。
int myint;
int* iptr = &myint;
func(iptr); // iptr doesn't point to a newed (dynamically-allocated) object
// std::shared_ptr, by default, uses delete on its managed pointer
// if there are no more references to that pointer
如果您在使用两个单独std::shared_ptr
的 s 来管理原始指针时不小心,您仍然可能会做错。
int* riptr = new int;
std::shared_ptr<int> iptr(riptr);
std::shared_ptr<int> iptr2(riptr); // WRONG!
关于原始指针的问题,两者本质上是相同的,但这不一定适用于std::shared_ptr
.
因为将指针作为单个参数的构造函数是显式的,所以你不能在这里使用赋值符号,因为它被认为是一个implicit conversion
.
您还可以在此处使用便捷功能 make_shared():
std::shared_ptr<parent> p2 = std::make_shared<parent>();
这种创建方式更快、更安全,因为它使用one
而不是two allocations
:一种用于对象,另一种用于共享指针用于控制对象的共享数据。