我有一堂课
class vlarray {
public:
double *p;
int size;
vlarray(int n) {
p = new double[n];
size = n;
for(int i = 0; i < n; i++)
p[i] = 0.01*i;
}
~vlarray() {
cout << "destruction" << endl;
delete [] p;
size = 0;
}
};
Run Code Online (Sandbox Code Playgroud)
当我在主要使用
int main() {
vlarray a(3);
{
vlarray b(3);
b.p[0] = 10;
for(int i = 0; i < 3; i++) {
cout << *(b.p+i) << endl;
}
a = b;
} // the magic happens here deallocation of b
for(int i = 0; i < 3; i++) {
cout << *(a.p+i) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
什么时候出现问题,为什么会出现这个问题以及如何避免这类问题?
人们似乎对这个问题的答案存在之间有些混乱,所以我我要去跳.
您的主要问题是您尚未定义自己的复制赋值运算符.相反,编译器为您生成一个天真的,所以当您运行时a = b,内部的指针b被复制到a.然后,当bdie和它的析构函数运行时,现在里面的指针a不再有效.另外,a原来的指针已被泄露.
您自己的复制赋值运算符将需要delete现有数组,分配一个新数组并复制您正在复制的对象的内容.
更进一步,您还需要定义一些其他的东西.这个要求被巧妙地概括为三条规则(C++ 03)或五条规则(C++ 11),并且在网上和你最喜欢的同行推荐的C++书中有很多解释可以教你如何满足它.
更好的是,你可以开始使用std::vector而不是手动分配所有东西,并避免这整个混乱:
struct vlarray {
std::vector<double> p;
vlarray(int n) {
p.resize(n);
for(int i = 0; i < n; i++)
p[i] = 0.01*i;
}
};
Run Code Online (Sandbox Code Playgroud)