我在c ++代码上有一个名为ThreeDigits的类。我以这种方式重载了+操作数:
ThreeDigits* ThreeDigits::operator+(const ThreeDigits &number) const
{
double result= getNumber()+number.getNumber();
ThreeDigits* new_result=new ThreeDigits(result);
return new_result;
}
但是当我写主要功能时:
ThreeDigits* first=new ThreeDigits(2.55998);
ThreeDigits* second=new ThreeDigits(5.666542);
ThreeDigits* result=first+second;
我收到以下编译错误: 类型ThreeDigits *和ThreeDigits *到二元运算符+
的无效操作数你能告诉我这是什么问题吗?感谢
答案 0 :(得分:12)
您正在尝试将指向对象的指针而不是对象本身求和。要调用重载的运算符,必须在对象上调用它,从而取消引用指针。
顺便说一句,使用new
创建所有这些对象是一种可怕的C ++方法;在C ++中,与Java / C#不同,只有在必要时才应使用new
,并在堆栈上分配所有其余部分。让operator+
返回指向新创建的对象的指针是令人厌恶的。
C ++编写代码的方式是:
ThreeDigits ThreeDigits::operator+(const ThreeDigits &number) const
{
return ThreeDigits(getNumber()+number.getNumber()); // construct a temporary and return it
}
// ...
ThreeDigits first(2.55998);
ThreeDigits second(5.666542);
ThreeDigits result=first+second;
顺便说一句,重载算术运算符的常用方法是首先重载赋值版本(+ =, - =,...),然后在它们上构建“普通”版本。有关运算符重载的详细信息,请参阅operator overloading FAQ。
答案 1 :(得分:3)
要使用您编写的运算符,您需要编写:ThreeDigits* result=*first+*second;
以取消引用指针。
但是,您的运营商至少存在两个问题:一,它违反了规范operator+
按值返回的最小意外原则。其次,它返回一个指向新内存的指针,除非小心,否则很可能会在各种情况下泄露。
看起来您可能来自Java背景,其中所有内容都是引用计数。相反,惯用的C ++实现将如下所示:
ThreeDigits ThreeDigits::operator+(const ThreeDigits &number) const
{
double result= getNumber()+number.getNumber();
return ThreeDigits(result);
}
用过:
ThreeDigits first(2.55998);
ThreeDigits second(5.666542);
ThreeDigits result = first+second;
答案 2 :(得分:1)
您没有取消引用指针。试试这个:
ThreeDigits* result = *first + *second;
答案 3 :(得分:1)
您的操作员接受两个ThreeDigits引用并返回ThreeDigits指针。
要使用您的运算符,必须取消引用first
和second
:
ThreeDigits* result = *first + *second;
此操作符具有不寻常的签名。 operator+
应返回ThreeDigits(即不是指向一个的指针)。对于您的运营商而言隐含新的(或malloc)数据是非常糟糕的做法,因为用户不会期望这样做。 RVO意味着无论如何返回副本都不是什么大问题。