Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用Unique_ptr确保工厂中的唯一对象_C++_Move_Factory_Unique Ptr - Fatal编程技术网

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
    保证单个
    unique_ptr
    容器拥有所持有指针的所有权。这意味着您无法复制唯一的\u 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 a
T*
并从中构造
std::unique\u ptr
,或者调用
std::make_unique
new
a
T
并将其包装成
unique\u ptr
。如果假设不是这样,并且
std::unique_ptr
被破坏,那么程序的行为是未定义的

禁止复制可以保证
delete
只被调用一次,而且通常不需要您额外的努力(即指针对象的生命周期与指针的生命周期完全相同)

您已经获得了
std::unique\u ptr
的“唯一性”。当你创建一个
std::unique_ptr
时,它不会以某种方式检查所有当前存在的
std::unique_ptr
,如果一个指针值相同,它会做一些不同的事情

相反,假设您以前使用过
new
ed a
T*
并从中构造
std::unique\u ptr
,或者调用
std::make_unique
new
a
T
并将其包装成
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;
};