首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >包含指针的对象的C++预分配向量

包含指针的对象的C++预分配向量
EN

Stack Overflow用户
提问于 2013-03-23 09:50:13
回答 3查看 856关注 0票数 0

我有以下结构:

代码语言:javascript
运行
复制
struct CacheNode {
  set<int> *value;
  int timestamp;
  CacheNode() : value(new set<int>()), timestamp(0) {}
};

我预先分配了它们的一个向量,如下所示:

代码语言:javascript
运行
复制
vector<CacheNode> V(10);

当我这样做时,向量中的每个CacheNode元素都指向其value字段中的相同set<int>。特别地,

代码语言:javascript
运行
复制
  V[0].value->insert(0);
  cout << V[1].value->size() << endl;

打印出1而不是我想要的0

预分配向量(或声明结构)以便每个CacheNode都有自己的set<int>实例的正确方法是什么?

(注意:我确实需要value是指向集合的指针,因为在我的应用程序中,某些CacheNodes共享集合是可能的。)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-23 09:55:48

您违反了% 3的规则。您已使用非普通构造函数创建了一个对象,但未能创建析构函数、复制构造函数或operator=

std::vector<blah> foo(10)创建了一个默认构造的blah,并在foo中创建了10个副本。因为您违反了3的规则,所以这10个副本都是相同的。

最简单的方法是去掉new

代码语言:javascript
运行
复制
struct CacheNode {
  std::set<int> value;
  int timestamp;
  CacheNode() : value(), timestamp(0) {}
};

另一种方法是使用unique_ptr进行生命周期管理,并显式复制:

代码语言:javascript
运行
复制
struct CacheNode {
  std::unique_ptr<std::set<int>> value;
  int timestamp;
  CacheNode() : value(new std::set<int>()), timestamp(0) {}
  CacheNode(CacheNode&&) = default; // C++11 feature
  CacheNode(CacheNode const& other):value(new std::set<int>( *other.value ) ), timestampe(other.timestamp) {}

  CacheNode& operator=(CacheNode const& other) {
    value.reset(new std::set<int>(*other.value));
    timestampe = other.timestamp;
    return *this;
  }
  CacheNode& operator=(CacheNode&& other) = default;
  // no need for ~CacheNode, unique_ptr handles it
};

当您想要从CacheNode中取出std::set<int>时,调用CacheNode().value.release()并存储生成的std::set<int>*

std::shared_ptr<std::set<int>>将允许共享std::set的所有权。

还有其他方法,包括使您的vector存储指针指向CacheNode,创建执行值语义的value_ptr<T>模板等。

在C++11中,这些是相对简单和安全的,因为std::vector将移动对象,并且在value_ptr<T>上移动语义不会创建新的T

我对您在不同的CacheNode之间共享std::set<int>的计划有点怀疑,因为一般来说,这很糟糕--事物的所有权/生命周期应该很清楚,在这种情况下,您有一些拥有std::set<int>CacheNode,而另一些不拥有这些std::set<int>(因为它们共享所有权)。shared_ptr可以绕过这个问题,但通常还有更好的解决方案。

票数 5
EN

Stack Overflow用户

发布于 2013-03-23 09:54:26

vector<CacheNode> V(10);创建一个初始CacheNode对象,然后将其复制10次。所以你有10个相同的对象。

您可以使用generate_n

代码语言:javascript
运行
复制
std::vector<CacheNode> v;
std::generate_n(std::back_inserter(v), 10u, [](){ return CacheNode{}; });

这是一个example program

票数 5
EN

Stack Overflow用户

发布于 2013-03-23 09:57:59

您将希望使用vector.assign(10, CacheNode()),因为您所做的主要是一种预留空间的方式。

你也应该照别人说的去做,提供虚拟析构函数之类的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15582508

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档