通过基类成员迭代

时间:2014-01-04 07:22:59

标签: c++ inheritance vector iterator

我有以下内容:

#include <vector>
#include <iostream>

template<typename T>
class Vector {
private:
  std::vector<T> base;

public:
  Vector(const std::vector<T> vec) {base = vec;}

  T& operator[](const int& index) {return base[index];}
  std::vector<T> getBase() const {return base;}
};


class BigNum : public Vector<int>
{
public:
  BigNum(const std::vector<int> init) : Vector(init) {}
};


int main()
{
  int arr[] = {6,3,7,6,2};
  std::vector<int> v(arr, arr + sizeof(arr) / sizeof(arr[0]));

  BigNum num(v);

  for(auto it = num.getBase().begin(); it != num.getBase().end(); ++it)
    {
      std::cout << *it << " ";  // What's going on here??
    }

  std::cout << "\n";

  for(int i = 0; i < 5; ++i)
    {
      std::cout << num.getBase()[i] << " ";
    }

  std::cout << "\n";
}

这两个循环的输出是:

30134336 0 7 6 2 
6 3 7 6 2 

这里发生了什么?第一个循环中的第一个数字(30134336)每次都会更改,但其余的数字是相同的。提前谢谢!

3 个答案:

答案 0 :(得分:1)

 std::vector<T> getBase() const {return base;}

该函数返回存储的vector的副本,因此您将在2(或每次迭代的不同vector)迭代完全不同的向量,这些向量在创建后很快就被销毁。大规模未定义的行为。将功能更改为

std::vector<T> const& getBase() const {return base;}

我将你的课改写为

template<typename T>
class Vector {
private:
  std::vector<T> base;

public:
  Vector(std::vector<T> vec)
  : base(std::move(vec))
  {}

  T& operator[](int index) {return base[index];}
  T const& operator[](int index) const {return base[index];}
  std::vector<T> const& getBase() const {return base;}
};


class BigNum : public Vector<int>
{
public:
  BigNum(std::vector<int> init) : Vector(std::move(init)) {}
};

使用C ++ 11,您可以将矢量初始化为

std::vector<int> v{6,3,7,6,2};

答案 1 :(得分:0)

  1. num.getBase()创建了base Vector成员的副本。
  2. num.getBase().begin()为该副本创建一个迭代器。
  3. 在分配auto it = num.getBase().begin()之后,num.getBase()创建的副本将被销毁。这使迭代器无效。
  4. 使用无效的迭代器是未定义的行为。任何事情都可能发生。
  5. 您可以通过将Vector::getBase()定义为

    来解决此问题
    const std::vector<T>& getBase() const { return base; }
    

    这样,num.getBase()将返回对原始Vector::base的引用,即副本的内容。您还必须使用std::vector::cbegin(),因为begin()会允许您修改原始向量,这与const std::vector<T>&返回类型相矛盾。

答案 2 :(得分:0)

你正在调用UB

由于auto it = num.getBase().begin()num.getBase().end()是两个不同的向量迭代器。

您可以使用:

  auto v1= num.getBase();
  for(auto it = v1.begin(); it != v1.end(); ++it)
  {
      std::cout << *it << " "; 
  }

或将getbase()更改为

std::vector<T> const& getBase() const {return base;}

相关问题