我有以下内容:
#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)每次都会更改,但其余的数字是相同的。提前谢谢!
答案 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)
num.getBase()
创建了base
Vector
成员的副本。num.getBase().begin()
为该副本创建一个迭代器。auto it = num.getBase().begin()
之后,num.getBase()
创建的副本将被销毁。这使迭代器无效。您可以通过将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;}