类型的无效操作数 - 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 指针。
要按照书面形式使用您的运算符,您必须取消引用 first
和 second
:
ThreeDigits* result = *first + *second;
这个操作符有一个不寻常的签名。 operator+
应该返回一个 ThreeDigits(即不是指向一个的指针)。对于您的操作员来说,隐式地新建(或 malloc)数据是非常糟糕的做法,因为用户不会想到这一点。 RVO 意味着无论如何归还副本并不是什么大不了的事。
【讨论】:
...如果他的类只是double
的包装器,即使复制它也会比堆分配快得多。
是的。出于某种原因,我们将副本与堆分配进行比较,这在这种情况下肯定是一个更昂贵的操作。以上是关于类型的无效操作数 - C++的主要内容,如果未能解决你的问题,请参考以下文章
返回对字符串对象的引用,错误:“const string&”类型的引用初始化无效。 C++
错误:“int”和“<未解析的重载函数类型>”类型的无效操作数到二进制“operator/”
错误消息:“float”和“int”类型的无效操作数到二进制“operator%”
使用了无效的操作数类型:array_uintersect 需要数组
错误! 'float' 和 'const char [2]' 类型的无效操作数到二进制 'operator<<' [关闭]