指针向量的迭代器

时间:2011-04-15 02:43:26

标签: c++ pointers vector iterator

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

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:错误:“operator=”中的“vec1_Itr = other->MyContainer::vecOne. std::vector<_Tp, _Alloc>::begin [with _Tp = MyStuff*, _Alloc = std::allocator<MyStuff*>]()”不匹配

     

候选人是:__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> > >&)

我也得到了operator!=的错误...另一个向量的另一组错误。

3 个答案:

答案 0 :(得分:3)

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

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

编辑0:

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

vector<MyStuff*>::const_iterator vec1_itr;

答案 1 :(得分:3)

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

另一方面,如果持有一个指针容器意味着你需要管理容器中的指针而你有两个这样的容器,那么你应该将容器移动到它自己的类中。尽量避免在一个类中管理多个资源。

答案 2 :(得分:3)

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

你的代码本身就是漏洞。

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

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

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

  

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

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

在您的情况下,您有两个解决方案:

  1. 推荐:由于此处不使用多态,因此请勿使用指针。 std::vector<MyStuff>非常好
  2. 如果您需要多态性,但未将其包含在此玩具示例中,请使用boost::ptr_vector<MyStuff>
  3. 奖励点:其中两个定义了合理的复制构造函数,赋值运算符和析构函数,因此您不必自己重写它们。

    修改

    如@David所述,如果你需要多态,你不能使用复制构造,因此需要:

    • clone方法或同等方法
    • 指针和动态内存分配

    boost::ptr_vector提供您所需的一切(复制时自动使用clone方法。)