为什么允许从一个对象创建多个唯一的指针?

时间:2019-03-29 15:00:37

标签: c++ pointers unique-ptr

为什么允许从单个对象创建多个唯一指针?

#include <iostream>
#include <memory>

using namespace std;    

class Class
{
public:
    Class(int a): int_(a){std::cout << "constr" << std::endl;}
    ~Class(){std::cout << "destr" << std::endl;}
    int int_;

};

int main()
{
    Class a(4);
    std::unique_ptr<Class> ptr = std::make_unique<Class>(a);
    std::unique_ptr<Class> ptr2 = std::make_unique<Class>(a);
    std::unique_ptr<Class> ptr3 = std::make_unique<Class>(a);
    std::cout << ptr->int_ << std::endl;
    std::cout << ptr2->int_ << std::endl;
    std::cout << ptr3->int_ << std::endl;

    return 0;
}

输出:

constr
4
4
4
destr
destr
destr
destr

3 个答案:

答案 0 :(得分:40)

为什么不呢?

您不是要创建指向同一unique_ptr实例的多个Class实例,而是要在堆上分配三个新的Class实例,这些实例是从{{1}复制构造的}。每个a都指向一个不同的实例。


unique_ptr

上面的意思是:在堆上创建std::unique_ptr<Class> ptr = std::make_unique<Class>(a); 的新实例,从Class复制构造,并将其所有权授予名为{{1 }}。

答案 1 :(得分:21)

  

为什么允许从单个对象创建多个唯一指针?

您不允许这样做*,所以您这样做是一件好事!

别忘了,这个:

std::unique_ptr<Class> ptr = std::make_unique<Class>(a);

这是**:

std::unique_ptr<Class> ptr(new Class(a));

不是这个:

std::unique_ptr<Class> ptr(&a);

std::make_unique创建一个事物,并给您一个unique_ptr。它通过将其参数转发给事物的构造函数来实现。诚然,当您传入一个现有对象的名称,导致使用复制构造函数时,这可能会造成混淆。

tl; dr:您正在创建a的副本。

*好吧,有了无操作删除器,您就可以安全地完成此操作,但让我们将对话保存另一天……
**或多或少…

答案 2 :(得分:11)

  

为什么允许从单个对象创建多个唯一指针?

由于该类是可复制的,因此您可以创建该对象的多个副本。


2中的“唯一”并不意味着指向的对象是其类的唯一实例。这意味着没有其他指针应具有指向对象的所有权。在您的示例中,每个唯一指针都指向一个单独的实例。每个指针都由其唯一拥有。

您可以违反这样的唯一性:

unique_ptr

可以:程序的格式正确,需要编译器进行编译。但是程序的行为将是不确定的,因此您不应该这样做。