在这种特定情况下是否有必要使运算符过载

时间:2018-12-13 06:18:38

标签: c++ class

#include <iostream>

class Complex
{
    double *arr;
    int n;

public:
    Complex() :n(0), arr(nullptr) {};
    Complex(const Complex &a)
    {
        if (this != a)
        {
            this->~Complex();
            copy(a);
         }
    }
    void copy(const Complex &a)
    {
        n = a.n;
        arr = new double[n];
        std::copy(a.arr, a.arr + n, arr);

    }
    ~Complex()
    {
        delete[] arr;
        n = 0;
    }
};
int main()
{


    getchar();
    getchar();
}

到目前为止,这是我所拥有的代码,是我创建了类Complex并创建了默认构造函数,并且想创建复制构造函数,这并不复杂,但是当我尝试编译它时,编译器说“没有运算符'!='匹配这些操作数”,现在,我知道this是指向进行中对象的指针,而a是我发送给函数的参数通过引用,所以我想知道,即使将它作为引用发送,我是否也需要将函数内部的该参数视为常规变量?这可能是问题吗?或者是别的什么?任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:2)

if (this != a)

是一种语法错误,因为this的类型是一个指针,而a的类型是对对象的引用。语法正确的形式为:

if (this != &a)

但是,在复制构造函数中完全没有必要。在复制构造函数中,您正在从另一个对象创建一个新对象。 this != &a将始终为true

第二,不要使用

this->~Complex();
函数中的

。您尚未构造对象。在其上调用析构函数有什么意义?同样,一旦调用了析构函数,该对象就死了。之后使用该对象会导致未定义的行为。

将您的功能简化为:

Complex(const Complex &a)
{
   copy(a);
}

答案 1 :(得分:2)

构造函数的工作是初始化正在创建的对象。那里还没有预先存在的对象,因此进行检查this != &a是没有意义的(正如您可能会说的,我已将其固定为比较地址)。条件永远为假的唯一方法是,如果有人编写了这段Machiavellian代码

Complex a(a);

从技术上讲,它是允许的,但是任何值得赞叹的编译器都将用nice shiny warning标记此行,需要对其进行修复。

现在,因为那里还没有对象(正在创建对象),所以调用它的析构函数会使您的程序具有未定义的行为。这意味着您无法根据C ++规范预测会发生什么,这会使您处于不稳定的境地。

直接的构造函数可以很好地完成工作:

Complex(const Complex &a) : n(a.n), arr(new double[a.n])
{
    std::copy(a.arr, a.arr + n, arr);
}

保护墨菲,而不是马基雅维利。防御性编程可以阻止某人意外地破坏您的代码。但是您不能阻止某人对此进行意图,因此不要写过于复杂的支票进行尝试。

答案 2 :(得分:1)

否,在if (this != a)中,有this是指针,而a是引用。

执行:if (this != &a)