C++ 使用Unique_ptr确保工厂中的唯一对象
我遇到了一个工厂的以下代码C++ 使用Unique_ptr确保工厂中的唯一对象,c++,move,factory,unique-ptr,C++,Move,Factory,Unique Ptr,我遇到了一个工厂的以下代码 T::create(std::forward(args)…。返回指向动态创建的对象的指针。所以基本上,如果两个对象有相同的地址,那么它们是相同的 unique_ptr保证单个unique_ptr容器拥有所持有指针的所有权。这意味着您无法复制唯一的\u ptr #pragma一次 #包括 #包括 模板 类池工厂{ 公众: 模板 T*getInstance(Args…Args){ _把你推回去( std::unique_ptr(T::create(std::forw
返回指向动态创建的对象的指针。所以基本上,如果两个对象有相同的地址,那么它们是相同的T::create(std::forward(args)…。
保证单个unique_ptr
容器拥有所持有指针的所有权。这意味着您无法复制唯一的\u ptrunique_ptr
#pragma一次
#包括
#包括
模板
类池工厂{
公众:
模板
T*getInstance(Args…Args){
_把你推回去(
std::unique_ptr(T::create(std::forward(args)…));
返回_createdItems.back().get();
}
~PoolFactory()=默认值;
公众:
std::vector_createdItems;
};
问题:
假设我们试图插入向量中已经存在的对象。因为我们使用的是工厂,如果对象已经存在,我们只想检索它。包含移动语义的架构如何保证这种行为?解释此代码时,在此工厂中,对象由
getInstance
参数标识。接口还建议调用者同时知道T
及其构造函数参数,以便他们可以自己构造T
此工厂的唯一用途是使每个对象成为单个对象
您需要一个映射
(args…->object
,而不是一个数组,这样首先您可以使用args…
查找现有对象,如果该对象尚不存在,则创建该对象。解释此代码,在这个工厂中,您的对象由getInstance
参数标识。接口还建议调用者同时知道T
及其构造函数参数,以便他们可以自己构造T
此工厂的唯一用途是使每个对象成为单个对象
您需要一个映射(args…->object
,而不是一个数组,这样,首先您可以使用args…
查找现有对象,如果该对象尚不存在,则创建该对象。您已经获得了std::unique\u ptr
的“唯一性”。当你创建一个std::unique_ptr
时,它不会以某种方式检查所有当前存在的std::unique_ptr
,如果一个指针值相同,它会做一些不同的事情
相反,假设您以前使用过new
ed aT*
并从中构造std::unique\u ptr
,或者调用std::make_unique
到new
aT
并将其包装成unique\u ptr
。如果假设不是这样,并且std::unique_ptr
被破坏,那么程序的行为是未定义的
禁止复制可以保证delete
只被调用一次,而且通常不需要您额外的努力(即指针对象的生命周期与指针的生命周期完全相同)您已经获得了std::unique\u ptr
的“唯一性”。当你创建一个std::unique_ptr
时,它不会以某种方式检查所有当前存在的std::unique_ptr
,如果一个指针值相同,它会做一些不同的事情
相反,假设您以前使用过new
ed aT*
并从中构造std::unique\u ptr
,或者调用std::make_unique
到new
aT
并将其包装成unique\u ptr
。如果假设不是这样,并且std::unique_ptr
被破坏,那么程序的行为是未定义的
禁止复制可以保证
delete
只调用一次,而且通常不需要您额外的努力(即指针对象的生命周期与指针的生命周期完全相同)这个问题的前提对我来说没有多大意义。在格式良好的程序中,向量中没有两个指针指向同一对象。当你用它作为问题的序言时,你似乎自己也理解它。你在这里混淆了“独特”的两个不同概念。有对象标识(基本上是指针)和对象相等性(在您的例子中,“使用相同的参数集创建”)。拥有身份意义上的独特对象是微不足道的(正如@StoryTeller所说)。拥有平等意义上的唯一对象需要某种方法来检查平等性(基于提供的args
)-这就是当前答案所指出的。此外,还不清楚您为什么担心移动语义。如果返回指针,则所有权将保留在工厂中。因此,没有物体必须/应该移动。这个问题的前提对我来说没有多大意义。在格式良好的程序中,向量中没有两个指针指向同一对象。当你用它作为问题的序言时,你似乎自己也理解它。你在这里混淆了“独特”的两个不同概念。有对象标识(基本上是指针)和对象相等性(在您的例子中,“使用相同的参数集创建”)。拥有身份意义上的独特对象是微不足道的(正如@StoryTeller所说)。拥有平等意义上的唯一对象需要某种方法来检查平等性(基于提供的args
)-这就是当前答案所指出的。此外,还不清楚您为什么担心移动语义。如果返回指针,则所有权将保留在工厂中。因此,不需要/不应该移动任何对象。从技术上讲,向量可以是映射(args…->object
(在某些情况下,它是最佳映射)。我猜你的意思是“…而不是对象的向量”或类似的东西?从技术上讲,向量可以是映射
#pragma once
#include <memory>
#include <vector>
template <typename T>
class PoolFactory {
public:
template <typename... Args>
T *getInstance(Args... args) {
_createdItems.push_back(
std::unique_ptr<T>(T::create(std::forward<Args>(args)...)));
return _createdItems.back().get();
}
~PoolFactory() = default;
public:
std::vector<std::unique_ptr<T>> _createdItems;
};