类型的无效操作数 - C++

Posted

技术标签:

【中文标题】类型的无效操作数 - C++【英文标题】:invalid operands of types - c++ 【发布时间】:2011-09-13 17:29:45 【问题描述】:

我在 c++ 代码中有一个名为 ThreeDigits 的类。我这样重载了 + 操作数:

ThreeDigits* ThreeDigits::operator+(const ThreeDigits &number) const


   double result= getNumber()+number.getNumber();
   ThreeDigits* new_result=new ThreeDigits(result);
   return new_result;

但是当我写在main函数上时:

    ThreeDigits* first=new ThreeDigits(2.55998);
    ThreeDigits* second=new ThreeDigits(5.666542);
    ThreeDigits* result=first+second;

我收到以下编译错误: ThreeDigits* 和 ThreeDigits* 类型的无效操作数到二元运算符+

你能告诉我是什么问题吗?谢谢

【问题讨论】:

你需要忘记new 怎么样:ThreeDigits* result=(*first)+(*second); ...在取消学习new 之后,开始学习如何accept 回答。 你说“接受”答案是什么意思? @Kerrek:过去一个小时左右的第四次,我看到 OP 的接受率为 0%,我不知道发生了什么 :) 【参考方案1】:

您正在尝试汇总 指向对象的指针,而不是对象本身。要调用重载运算符,您必须在对象上调用它,从而取消对指针的引用。

顺便说一句,使用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。

【讨论】:

只是好奇,但是为什么你在前两行使用()-style初始化,在最后一行使用=-style初始化? @Rob:我真的不知道... :) 可能是因为它仍然是原始代码的复制粘贴,可能是因为此刻拥有一个更“自然”的感觉像x=y+z这样的表达式。【参考方案2】:

要按原样使用您的运算符,您需要编写: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;

【讨论】:

【参考方案3】:

您没有取消引用指针。试试这个:

ThreeDigits* result = *first + *second;

【讨论】:

这使它可以编译,但只会更深入地挖掘问题......这段代码中根本不应该有指针。【参考方案4】:

您的操作员接受两个 ThreeDigits 引用并返回一个 ThreeDigits 指针。

要按照书面形式使用您的运算符,您必须取消引用 firstsecond

ThreeDigits* result = *first + *second;

这个操作符有一个不寻常的签名。 operator+ 应该返回一个 ThreeDigits(即不是指向一个的指针)。对于您的操作员来说,隐式地新建(或 malloc)数据是非常糟糕的做法,因为用户不会想到这一点。 RVO 意味着无论如何归还副本并不是什么大不了的事。

【讨论】:

...如果他的类只是 double 的包装器,即使复制它也会比堆分配快得多。 是的。出于某种原因,我们将副本与堆分配进行比较,这在这种情况下肯定是一个更昂贵的操作。

以上是关于类型的无效操作数 - C++的主要内容,如果未能解决你的问题,请参考以下文章

返回对字符串对象的引用,错误:“const string&”类型的引用初始化无效。 C++

错误:“int”和“<未解析的重载函数类型>”类型的无效操作数到二进制“operator/”

错误消息:“float”和“int”类型的无效操作数到二进制“operator%”

如何解决操作数数据类型 nvarchar 对减号运算符无效

使用了无效的操作数类型:array_uintersect 需要数组

错误! 'float' 和 'const char [2]' 类型的无效操作数到二进制 'operator<<' [关闭]