为什么允许从单个对象创建多个唯一指针?
#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
答案 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
† 可以:程序的格式正确,需要编译器进行编译。但是程序的行为将是不确定的,因此您不应该这样做。