c++中的操作符重载
Operator Overloading in C++
我需要重载c++中的*操作符。因此,我创建了一个名为Element的类,它必须重载此操作符才能处理存储在其中的双精度值。这是我在实现文件中所做的:
#include "Element.h"
#include <iostream>
using namespace std;
// Other code that is not relevant
Element Element::operator * ( const Element &obj)
{
d *= obj.d;
return *this;
}
这行不通。它抛出一个错误:"没有匹配'8 * c'中的'operator*'
在主文件中我有:
d = a = 8 * c - 4 + b;
其中d、a、c和b都是Element
你必须明白你在这里做什么,你重载了Element类的'*'操作符,但是你这样做的同时期望另一个元素有一个'参数'。
你写的代码实际上是期望这种代码
Element v, w, a;
a = v * w;
如前所述,您可能想看一下:http://www.learncpp.com/cpp-tutorial/92-overloading-the-arithmetic-operators/
这是因为您仅为Element * Element
重载了操作符*,而对于c * 8
,您必须实现Element Element::operator * ( const int i)
可以用非成员重载(如
)匹配8 * c表达式(int, Element)Element operator* (const Element& leftHandSide, const Element& rightHandSide){
return Element( leftHandSide.d * rightHandSide.d);
}
通过使用const Element&
,您可以使用具有Element::Element(int )
等签名的构造函数进行类型转换。
您现有的操作符实现允许您将两个Element
对象相乘。但是,根据"主文件"中的客户端代码,您需要能够将Element对象乘以标量值;
Element Element::operator * ( const double scalar ) const
{
const Element e( d * scalar );
return e;
}
这里我假设你的Element类有一个构造函数,它接受一个标量参数,并把它赋值给d。
还要注意,你现有的操作符*的实现在语义上是奇怪的,因为它改变了d的内部状态(带*=)。这肯定不是你想要的……
我有一个解决方案,并警告您的操作符过载。
解决方案:
#include <iostream>
using namespace std;
struct Element {
double d;
Element(double d) {this->d = d;}
Element operator*(const Element &obj) {
d *= obj.d;
return *this;
}
};
Element operator*(const int i, const Element& e) {
return Element(static_cast<double>(i) * e.d);
}
ostream& operator<<(ostream& os, const Element& e) {
os << e.d;
return os;
}
int main() {
Element e(2);
cout << "Product of 8 and e: " << 8*e << 'n';
// This shows why your overload is a bad idea:
Element a(3);
cout << "a is " << a << 'n'; // prints 3
cout << "Now its product with e is: " << a*e << 'n'; // prints 6
cout << "Surprise: a is now " << a << 'n'; // prints 6
}
你原来的重载没有工作,因为它甚至没有被调用。您的表达式类似于
a = 8*c
,其中8是int类型,当c++从左到右解析这个表达式时,它看到8是int类型,并试图在int类型中搜索操作符*(const Element&)的重载,但它找不到它,因为它不知道也不应该知道任何关于您自己的用户定义类型的信息。因此,如果您希望自己的类与其他类型交互,则需要将operator*的重载作为成员函数嵌入到其他类型中,或者像我在解决方案中所做的那样将其声明为外部函数。
现在是警告。您的原始操作符重载定义不清,因为它修改了原始对象,这被认为是一种意外行为。我在上面的代码中展示了这一点。就像8乘以2会得到16,但同时8除以16。真正需要做的是在乘法运算符中创建一个新元素并返回它:
struct Element {
double d;
Element(double d) {this->d = d;}
Element operator*( const Element &obj) {
return Element(this->d * obj.d);
}
};
该死的这些答案花了很多时间…
- 重载操作符+:表达式必须是整型或无作用域枚举类型
- 重载操作符
- 如何重载操作符==外模板类使用友元函数
- 重载*操作符,使其在左右两边都工作
- 重载操作符<对于非随机迭代器
- 在c++中重载操作符的时间和原因
- 如何在c++中重载=操作符来通过引用进行复制
- 如何在c++中获取定义为友元的重载操作符的地址
- 使用重载操作符的文件操作表达式没有给出预期的结果
- 重载操作符()
- 重载操作符()并在类内使用
- 类中的重载操作符+
- 定时使用重载操作符
- c++带类的重载操作符
- 用列表容器重载[]操作符
- 重载操作符=
- 任何重载操作符()的静态检测
- 重载操作符以处理类对象
- 在使用另一个类的类中重载操作符==
- 派生类和基类中的重载操作符不同