我在使用以下代码时遇到了一些麻烦:
#include <iostream>
#incldue <vector>
template <typename ElemType>
class A{
private:
std::vector<ElemType> data;
public:
A() {};
A(int capacity) {
data.reserve(capacity);
}
int GetCapacity() {
return data.capacity();
}
};
int main() {
A<int> a;
a = A<int>(5);
std::cout << a.GetCapacity() << std::endl;
}
输出为0.可能是什么问题?
答案 0 :(得分:11)
std::vector<T>
的复制构造函数和赋值运算符不需要复制向量的容量,只复制元素。因为行a = A<int>(5)
间接调用赋值运算符(在创建临时值之后),a
中的向量没有容量。
尝试将main的前两行更改为A<int> a(5)
并查看结果。
如果您绝对需要将容量从一个实例传输到另一个实例的能力,则需要定义A的赋值和复制构造函数,以复制数据并分配容量。
答案 1 :(得分:2)
因为您尚未实现A
的副本分配,所以保留了向量的容量。编译器生成A
的副本分配,确保仅复制向量的元素。向量的复制构造函数(和复制赋值)不需要保留源向量对象的容量。它复制元素,保留向量的size
。
这意味着,如果您将A
的副本分配定义为:
A& operator = (const A & a)
{
data = a.data;
}
它仍会打印0
。
您可以通过将副本分配实现为:
来实现所需的行为 A& operator = (const A & a)
{
data.reserve(a.capacity());
data.insert(data.end(), a.begin(), a.end());
}
请注意,.insert()
仅复制元素,因为.size()
更改了元素,但.capacity
保持不变。这就是您需要明确调用.reserve()
。
答案 2 :(得分:1)
这是因为您要分配给a,分配只会复制值和容量。
如果你想要具有设定容量的构造,那么。
A<int> a(5);
如果您希望通过作业进行转移,则需要编写自己的作业运算符
A& operator=(const A& a)
{
if(&a!=this)
{
data.assign(a.data);
data.reserve(a.capacity);
}
return *this;
}