#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是我发送给函数的参数通过引用,所以我想知道,即使将它作为引用发送,我是否也需要将函数内部的该参数视为常规变量?这可能是问题吗?或者是别的什么?任何帮助表示赞赏!
答案 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)