指针向量的迭代器

发布于 2024-11-01 06:40:43 字数 1805 浏览 2 评论 0 原文

我读了另一篇文章,回答了有关指针向量迭代器的问题。我尝试在代码中使用相同的概念,但收到一些编译错误。我的代码所基于的代码示例是:

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终陌 2024-11-08 06:40:43

您忘记取消引用迭代器。试试这个:

vecOne.push_back(new MyStuff( **vec1_itr ));

编辑 0:

是的,应该是双重取消引用(上面已修复)。它应该是 const_terator,因为您正在处理包含对象的 const:

vector<MyStuff*>::const_iterator vec1_itr;

You forgot to dereference the iterators. Try this instead:

vecOne.push_back(new MyStuff( **vec1_itr ));

Edit 0:

Yes, should be double dereference (fixed above). And it should be the const_terator instead since you are dealing with const containing object:

vector<MyStuff*>::const_iterator vec1_itr;
去了角落 2024-11-08 06:40:43

要么不要将参数作为 const,要么将 vec1_itr 声明为 const_iterator。这里的问题是,vecOne.begin() 返回一个 const_iterator,因为容器是 const。如果您想更改容器,则必须删除 const 限定符。

附带说明一下,如果持有一个指针容器意味着您需要管理容器中的指针,并且您有两个这样的容器,那么您应该将容器移动到它自己的类中。尽量避免在一个类中管理多个资源。

Either don't take the parameter as const or declare vec1_itr as a const_iterator. The issue here is that vecOne.begin() returns a const_iterator because the container is const. If you want to change the container you'll have to remove the const 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.

玻璃人 2024-11-08 06:40:43

<强>!!内存泄漏警报!!

您的代码存在泄漏。

从复制构造函数(std::bad_alloc?)中抛出的任何异常都会导致内存泄漏,因为传递到向量中的内存永远不会被清理(析构函数不会被调用,因为该对象从未被构造过)。

当然,您可以添加所需的 try/catch,但我警告您代码很快就会变得笨拙(您需要几个)。

这是违反资源管理规则1的直接结果:

一个对象应该管理最多一个资源,在这种情况下它不应该做任何其他事情。

这意味着,如果您的对象是一个业务对象(内部有应用程序逻辑),那么它不应该直接处理资源管理,而应该使用已经存在的管理器。

对于您的情况,您有两种解决方案:

  1. 推荐:由于您此处不使用多态性,因此不要使用指针。 std::vector 完全没问题
  2. 如果您需要多态性,但没有将其包含在此玩具示例中,则使用 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 the vector 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:

An object should manage at most one resource, in which case it should not be doing anything else.

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:

  1. Recommended: since you do not use polymorphism here, don't use pointers. std::vector<MyStuff> is perfectly fine
  2. If you need polymorphism, but didn't included it in this toy example, then use boost::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:

  • a clone method, or equivalent
  • pointers and dynamic memory allocation

boost::ptr_vector provide all you need for this (with automatic use of the clone method when copying).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文