c++ - "Rule of Three"的实现出错

标签 c++ delete-operator rule-of-three

下面是“三法则”的错误实现,我试图理解它。

调试程序时,我发现调试器在清理 int *k 时出现问题,可以通过定义 int *k = nullptr 或简单设置来解决它在复制构造函数中是合理的。

但是,我不明白程序的错误(访问冲突)是如何产生的。

我确实知道,在复制赋值构造函数v1int *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)的有效 kother< 的蹩脚 k 交换.

然后,当调用 v1 的析构函数时,它会对蹩脚的 k --> 访问冲突调用 delete[] k

解决方案

让你的复制构造函数进行复制。或者至少,让它正确初始化k(例如nullptr)。

关于c++ - "Rule of Three"的实现出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55146122/

相关文章:

c++ - vc++ 中预期的常量表达式

c++ - 在传递函数指针时是否应该转发有关 noexcept-ness 的知识?

c++ - 为什么我不能将元素重新分配给使用 delete [] 释放的数组?

c++ - 是否可以在 C++ 中使用 delete 删除 C POD?

c++ - 我违反了三原则吗?

c++ - 如何有效地将数组的一系列值与给定数字相乘?

c++ - 从 dll 启动 Qt GUI(在 DLLStart 函数中)

sql - 防止在 SQL Server 的 SQL 语句的一部分中记录计数

c++ - 三法则的异常(exception)?