我读了另一篇文章,回答了有关指针向量迭代器的问题。我尝试在代码中使用相同的概念,但收到一些编译错误。我的代码所基于的代码示例是:
vector<c*> cvect;
cvect.push_back(new sc);
vector<c*>::iterator citer;
for(citer=cvect.begin(); citer != cvect.end(); citer++) {
(*citer)->func();
}
我想使用类似的概念为一个类创建一个深层复制构造函数,该类具有两个数据成员,这两个数据成员是指向对象的指针的向量。我的代码与此类似:
class MyContainer {
vector<MyStuff*> vecOne;
vector<MyStuff*> vecTwo;
public:
MyContainer(const MyContainer& other);
};
MyContainer::MyContainer(const MyContainer& other) {
// copy vector one
vector<MyStuff*>::iterator vec1_itr;
for (vec1_itr = other.vecOne.begin(); vec1_itr != other.vecOne.end(); vec1_itr++) {
vecOne.push_back(new MyStuff(vec1_itr));
}
// copy vector two
vector<MyStuff*>::iterator vec2_itr;
for (vec2_itr = other.vecTwo.begin(); vec2_itr != other.vecTwo.end(); vec2_itr++) {
vecTwo.push_back(new MyStuff(vec2_itr));
}
}
我收到一些编译错误,例如:
/path/MyContainer.cpp:38:错误:“vec1_Itr = other->MyContainer::vecOne”中的“operator=
”不匹配。 std::vector<_Tp, _Alloc>::begin [with _Tp = MyStuff*, _Alloc = std::allocator]()
'
候选者是:__gnu_cxx::__normal_iterator; > >& __gnu_cxx::__normal_iterator; > >::operator=(const __gnu_cxx::__normal_iterator > >&)
我还收到 的错误运算符!= ...以及另一个向量的另一组相同的错误。
I read another post that answered a question regarding iterators for vectors of pointers. I tried to use the same concept in my code but I receive some compilation errors. The code sample I was basing my code on is:
vector<c*> cvect;
cvect.push_back(new sc);
vector<c*>::iterator citer;
for(citer=cvect.begin(); citer != cvect.end(); citer++) {
(*citer)->func();
}
I want to use a similar concept to create a deep copy constructor for a class that has two data members that are vectors of pointers to objects. My code is similar to this:
class MyContainer {
vector<MyStuff*> vecOne;
vector<MyStuff*> vecTwo;
public:
MyContainer(const MyContainer& other);
};
MyContainer::MyContainer(const MyContainer& other) {
// copy vector one
vector<MyStuff*>::iterator vec1_itr;
for (vec1_itr = other.vecOne.begin(); vec1_itr != other.vecOne.end(); vec1_itr++) {
vecOne.push_back(new MyStuff(vec1_itr));
}
// copy vector two
vector<MyStuff*>::iterator vec2_itr;
for (vec2_itr = other.vecTwo.begin(); vec2_itr != other.vecTwo.end(); vec2_itr++) {
vecTwo.push_back(new MyStuff(vec2_itr));
}
}
I get some compilation errors like:
/path/MyContainer.cpp:38: error: no match for 'operator=
' in 'vec1_Itr = other->MyContainer::vecOne. std::vector<_Tp, _Alloc>::begin [with _Tp = MyStuff*, _Alloc = std::allocator<MyStuff*>]()
'
candidates are: __gnu_cxx::__normal_iterator<MyStuff*, std::vector<MyStuff, std::allocator<MyStuff> > >& __gnu_cxx::__normal_iterator<MyStuff*, std::vector<MyStuff, std::allocator<MyStuff> > >::operator=(const __gnu_cxx::__normal_iterator<MyStuff*, std::vector<MyStuff, std::allocator<MyStuff> > >&)
I also get an error for operator!=
... And another set of the same errors for the other vector.
发布评论
评论(3)
您忘记取消引用迭代器。试试这个:
编辑 0:
是的,应该是双重取消引用(上面已修复)。它应该是 const_terator,因为您正在处理包含对象的 const:
You forgot to dereference the iterators. Try this instead:
Edit 0:
Yes, should be double dereference (fixed above). And it should be the
const_terator
instead since you are dealing withconst
containing object:要么不要将参数作为
const
,要么将vec1_itr
声明为const_iterator
。这里的问题是,vecOne.begin()
返回一个const_iterator
,因为容器是const
。如果您想更改容器,则必须删除const
限定符。附带说明一下,如果持有一个指针容器意味着您需要管理容器中的指针,并且您有两个这样的容器,那么您应该将容器移动到它自己的类中。尽量避免在一个类中管理多个资源。
Either don't take the parameter as
const
or declarevec1_itr
as aconst_iterator
. The issue here is thatvecOne.begin()
returns aconst_iterator
because the container isconst
. If you want to change the container you'll have to remove theconst
qualifier.On a side note, if holding a container of pointers means you need to manage the pointers in the container and you have two such containers then you should move the container into a class of its own. Try to avoid managing more than one resource in a class.
<强>!!内存泄漏警报!!
您的代码存在泄漏。
从复制构造函数(std::bad_alloc?)中抛出的任何异常都会导致内存泄漏,因为传递到向量中的内存永远不会被清理(析构函数不会被调用,因为该对象从未被构造过)。
当然,您可以添加所需的
try/catch
,但我警告您代码很快就会变得笨拙(您需要几个)。这是违反资源管理规则1的直接结果:
这意味着,如果您的对象是一个业务对象(内部有应用程序逻辑),那么它不应该直接处理资源管理,而应该使用已经存在的管理器。
对于您的情况,您有两种解决方案:
std::vector
完全没问题boost::ptr_vector
< em>奖励点:它们两个定义了合理的复制构造函数、赋值运算符和析构函数,因此您不必自己重写它们。
编辑:
正如@David所指出的,如果您需要多态性,则不能使用复制构造,因此需要:
clone
方法,或等效的boost::ptr_vector
提供了您所需的一切(复制时自动使用clone
方法)。!! MEMORY LEAK ALERT !!
Your code, as is, is leaky.
Any exception thrown from within the copy constructor (
std::bad_alloc
?) will cause a memory leak because the memory passed into thevector
will never be cleaned-up (the destructor won't be called since the object was never constructed in the first place).You could, of course, add the required
try/catch
, though I warn you that the code will soon get clunky (you need several).This is a direct result of violating rule 1 of resources management:
This means that if your object is a business object (with application logic inside) then it should not deal with resource management directly, but instead use already existing managers.
In your case, you have two solutions:
std::vector<MyStuff>
is perfectly fineboost::ptr_vector<MyStuff>
Bonus Point: the two of them define sensible copy constructors, assignment operators and destructors, so that you won't have to rewrite them yourself.
EDIT:
As noted by @David, if you need polymorphism, you cannot use copy construction, and thus need:
clone
method, or equivalentboost::ptr_vector
provide all you need for this (with automatic use of theclone
method when copying).