下面是“三法则”的错误实现,我试图理解它。
调试程序时,我发现调试器在清理 int *k
时出现问题,可以通过定义 int *k = nullptr
或简单设置来解决它在复制构造函数中是合理的。
但是,我不明白程序的错误(访问冲突)是如何产生的。
我确实知道,在复制赋值构造函数v1
的int *k
不再指向有效的内存地址之后。
class Vector2 {
public:
std::string name = "default";
int* k;
Vector2(int s, std::string n) : k(new int[s]), name(n) {
}
Vector2(const Vector2 &other) {
std::cout<< "Copy constructor: " << name << std::endl;
}
~Vector2() {
std::cout << "Deleting: " << name << std::endl;
delete[] k;
}
void swap(Vector2& other) {
using std::swap;
swap(k, other.k);
}
Vector2& operator=(Vector2 other) {
std::cout << "Copy assignment constructor: " << name << std::endl;
swap(other);
return *this;
}
};
int main() {
Vector2 v1 = Vector2(2, "v1");
Vector2 v2 = Vector2(4, "v2");
v1 = v2;
std::cout << &v1 << " " << &v2 << std::endl;
std::cout << &v1.k << " " << &v2.k << std::endl;
return 0;
}
下面是上面程序的控制台输出:
Copy constructor: default
Copy assignment constructor: v1
Deleting: default
0000001B5611FA28 0000001B5611FA78
0000001B5611FA50 0000001B5611FAA0
Deleting: v2
Deleting: v1
16:18:42: The program has unexpectedly finished.
最佳答案
实际上非常简单:您的复制构造函数不会进行复制。事实上,它没有初始化任何成员,因此这个构造函数创建的任何实例都是垃圾。
对于operator=(Vector2 other)
的调用,复制构造函数被调用来创建other
(这是三法则的要点),所以other
充满了废话。
然后,将 this
(又名 v1
)的有效 k
与 other< 的蹩脚
.k
交换
然后,当调用 v1
的析构函数时,它会对蹩脚的 k
--> 访问冲突调用 delete[] k
。
解决方案
让你的复制构造函数进行复制。或者至少,让它正确初始化k
(例如nullptr
)。
关于c++ - "Rule of Three"的实现出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55146122/