3

为什么下面的代码编译

shared_ptr<parent> p(new parent);

而下面的没有

shared_ptr<parent> p2 = new parent;

是否有任何理由不允许 shared_ptr 使用“=”符号?

一般来说,如果一个指针像

int *p = new int;

应该与

int *p(new int);

不是吗?

4

2 回答 2

4

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.

于 2013-08-19T03:54:23.367 回答
3

因为将指针作为单个参数的构造函数是显式的,所以你不能在这里使用赋值符号,因为它被认为是一个implicit conversion.

您还可以在此处使用便捷功能 make_shared():

std::shared_ptr<parent> p2 = std::make_shared<parent>();

这种创建方式更快、更安全,因为它使用one而不是two allocations:一种用于对象,另一种用于共享指针用于控制对象的共享数据。

于 2013-08-19T03:59:09.810 回答