0

我有以下结构:

struct CacheNode {
  set<int> *value;
  int timestamp;
  CacheNode() : value(new set<int>()), timestamp(0) {}
};

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

vector<CacheNode> V(10);

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

  V[0].value->insert(0);
  cout << V[1].value->size() << endl;

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

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

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

4

3 回答 3

5

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

您可以使用generate_n

std::vector<CacheNode> v;
std::generate_n(std::back_inserter(v), 10u, [](){ return CacheNode{}; });

这是一个示例程序

于 2013-03-23T01:54:25.587 回答
5

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

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

最简单的方法是取消new

struct CacheNode {
  std::set<int> value;
  int timestamp;
  CacheNode() : value(), timestamp(0) {}
};

另一种方法是使用 aunique_ptr进行生命周期管理,并明确复制:

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
};

当你想std::set<int>取出你的CacheNode,调用CacheNode().value.release()并存储结果std::set<int>*

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

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

在 C++11 中,这些相对容易和安全,因为std::vector会移动事物,并且在 a 上移动语义value_ptr<T>不会创建新的T.

std::set<int>我对您在不同人之间共享的计划持怀疑态度CacheNode,因为总的来说这是难闻的气味-事物的所有权/生命周期应该很清楚,在这种情况下,您有一些CacheNode拥有,std::set<int>而另一些则不拥有(因为他们共享所有权)。Ashared_ptr可以解决这个问题,但通常有更好的解决方案。

于 2013-03-23T01:55:48.360 回答
-1

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

另外,您应该按照其他人所说的去做,提供虚拟析构函数等。

于 2013-03-23T01:57:59.430 回答