C++ 中的运算符重载

发布于 2024-12-03 06:11:28 字数 456 浏览 0 评论 0原文

我需要在 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类的对象

I need to overload the * operator in c++. So I have made a class called Element which must overload this opperator to work on a double value stored within it. This is what I have done in the implementation file:

#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;
}

This doesn't work. It throws an error saying: "no match for 'operator*' in '8 * c'

In the main file I have:

d = a = 8 * c - 4 + b;

where d, a, c and b are all objects of class Element

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烟火散人牵绊 2024-12-10 06:11:28

您确实必须了解您在这里所做的事情,您正在重载 Element 类的“*”运算符,但您这样做的同时期望另一个元素具有“参数”。

您编写的代码实际上期望这种代码

Element v, w, a;
a = v * w;

如上所述,您可能需要看一下: http://www.learncpp.com/cpp-tutorial/92-overloading-the-arithmetic-operators/

You really have to understand what you are doing here, you are overloading the '*' operator for the Element class, but you're doing so while expecting another element has a 'parameter'.

The code you wrote is actually expecting this kind of code

Element v, w, a;
a = v * w;

As mentionned, you might want to take a look at : http://www.learncpp.com/cpp-tutorial/92-overloading-the-arithmetic-operators/

十六岁半 2024-12-10 06:11:28

这是因为您仅对 Element * Element 重载了运算符 *,而对于 c * 8 您必须实现 Element Element::operator * ( const int i)

that's because you overloaded operator * only for Element * Element, while for c * 8 you would have to implement Element Element::operator * ( const int i)

信仰 2024-12-10 06:11:28

您可以将 8 * c 表达式 (int, Element) 与非成员重载相匹配,例如

Element operator* (const Element& leftHandSide, const Element& rightHandSide){
   return Element( leftHandSide.d * rightHandSide.d);
}

通过使用 const Element& 您可以使用带有 Element::Element 等签名的构造函数(int ) 用于类型转换。

You can match the 8 * c expression (int, Element) with a non-member overload like

Element operator* (const Element& leftHandSide, const Element& rightHandSide){
   return Element( leftHandSide.d * rightHandSide.d);
}

By using const Element& you can make use of a constructor with a signature like Element::Element(int ) for type conversion.

顾北清歌寒 2024-12-10 06:11:28

您现有的运算符实现允许您将两个 Element 对象相乘。
但是,根据“主文件”中的客户端代码,您需要能够将 Element 对象乘以标量值;在本例中为 8。

所以你需要的是一个额外的运算符,它将双精度作为其参数:
如下所示:

Element Element::operator * ( const double scalar ) const
{
    const Element e( d * scalar );
    return e;
}

这里我假设您的 Element 类有一个构造函数,该构造函数采用单个标量参数,并将其分配给 d。

另请注意,您现有的运算符 * 实现在语义上很奇怪,
因为它改变了 d 的内部状态(使用 *= )。
这几乎肯定不是你想要的......

Your existing operator implementation allows you to multiply two Element objects together.
But, according to the client code in your 'main file', you need to be able to multiply an Element object by a scalar value; 8 in this case.

So what you need is an additional operator which takes a double as its parameter:
Something like the following:

Element Element::operator * ( const double scalar ) const
{
    const Element e( d * scalar );
    return e;
}

Here I am assuming that your Element class has a constructor which takes a single scalar parameter, and assigns it to d.

Note also that your existing implementation of operator* is semantically strange,
as it mutates the internal state of d (with *= ).
This is almost certainly not what you want...

一城柳絮吹成雪 2024-12-10 06:11:28

我为您提供了一个解决方案,并针对您的操作员过载发出了警告。

解决方案:

#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);
    }
};

该死的这些答案太糟糕了时间...我应该工作:\

I have a solution for you and a warning for your operator overload.

Solution:

#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
}

Your original overload did not work, cause it wasn't even called. Your expression was similar to

a = 8*c

where 8 is of type int and when C++ parses this expression from left to right it sees that 8 is of type int and tries to search for an overload of operator*(const Element&) in the type int and it cannot find it, cause it does not know and is not supposed to know anything about your own user-defined type. So if you want your own class to interact with the other types you either need to embed an overload of operator* as a member function into that other type or declare it as the external function like I did in my solution.

Now the warning. Your original operator overload is ill-defined, cause it modifies the original object, which is considered to be an unexpected behavior. I show this in the code above. It's like multiplying 8 by 2 would give you 16, but at the same time make 16 out of your 8. What you really want to do is to create a new element in your multiplication operator and return it:

struct Element {
    double d;
    Element(double d) {this->d = d;}
    Element operator*( const Element &obj) {
        return Element(this->d * obj.d);
    }
};

Damn these answers take heck a lot of time... I should be working though :\

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文