我有以下结构:
struct CacheNode {
set<int> *value;
int timestamp;
CacheNode() : value(new set<int>()), timestamp(0) {}
};
我预先分配了它们的一个向量,如下所示:
vector<CacheNode> V(10);
当我这样做时,向量中的每个CacheNode
元素都指向其value
字段中的相同set<int>
。特别地,
V[0].value->insert(0);
cout << V[1].value->size() << endl;
打印出1
而不是我想要的0
。
预分配向量(或声明结构)以便每个CacheNode
都有自己的set<int>
实例的正确方法是什么?
(注意:我确实需要value
是指向集合的指针,因为在我的应用程序中,某些CacheNodes共享集合是可能的。)
发布于 2013-03-23 09:55:48
您违反了% 3的规则。您已使用非普通构造函数创建了一个对象,但未能创建析构函数、复制构造函数或operator=
。
std::vector<blah> foo(10)
创建了一个默认构造的blah
,并在foo
中创建了10个副本。因为您违反了3的规则,所以这10个副本都是相同的。
最简单的方法是去掉new
struct CacheNode {
std::set<int> value;
int timestamp;
CacheNode() : value(), timestamp(0) {}
};
另一种方法是使用unique_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
};
当您想要从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
可以绕过这个问题,但通常还有更好的解决方案。
发布于 2013-03-23 09:54:26
vector<CacheNode> V(10);
创建一个初始CacheNode
对象,然后将其复制10次。所以你有10个相同的对象。
您可以使用generate_n
std::vector<CacheNode> v;
std::generate_n(std::back_inserter(v), 10u, [](){ return CacheNode{}; });
这是一个example program。
发布于 2013-03-23 09:57:59
您将希望使用vector.assign(10, CacheNode())
,因为您所做的主要是一种预留空间的方式。
你也应该照别人说的去做,提供虚拟析构函数之类的。
https://stackoverflow.com/questions/15582508
复制相似问题