C++ 的哪个变体?我应该使用运算符重载吗?而且,为什么?

发布于 2024-12-14 02:29:56 字数 1094 浏览 0 评论 0原文

这里给出了加法运算符 (+) 重载的 3 种变体。

我应该使用哪种变体以及为什么?

class MyClass {
    int myInteger;
    double myDouble;
    public:
        MyClass(int i, double d) {
        myInteger = i;
        myDouble = d;
    }

    // Variation - 1
    //--------------
    MyClass operator +(MyClass rhsObj) {
        return MyClass(this->myInteger + rhsObj.myInteger, this->myDouble + rhsObj.myDouble);
    }

    // Variation - 2
    //--------------
    MyClass &operator +(MyClass &rhsObj) {
        rhsObj.myInteger = this->myInteger + rhsObj.myInteger;
        rhsObj.myDouble = this->myDouble + rhsObj.myDouble;

        return rhsObj;
    }

    // Variation - 3
    //--------------    
    MyClass &operator +(MyClass &rhsObj) {
        this->myInteger = this->myInteger + rhsObj.myInteger;
        this->myDouble = this->myDouble + rhsObj.myDouble;

        return *this;
    }
};


int main() {
    MyClass objOne(10, 10.5);
    MyClass objTwo(20, 20.5);

    MyClass objThree = objOne + objTwo;
}

赋值运算符(=)应该是什么情况?应该使用哪种变体?

Here 3 variations of the overloading of addition operator (+) are given.

Which variation should I use and why?

class MyClass {
    int myInteger;
    double myDouble;
    public:
        MyClass(int i, double d) {
        myInteger = i;
        myDouble = d;
    }

    // Variation - 1
    //--------------
    MyClass operator +(MyClass rhsObj) {
        return MyClass(this->myInteger + rhsObj.myInteger, this->myDouble + rhsObj.myDouble);
    }

    // Variation - 2
    //--------------
    MyClass &operator +(MyClass &rhsObj) {
        rhsObj.myInteger = this->myInteger + rhsObj.myInteger;
        rhsObj.myDouble = this->myDouble + rhsObj.myDouble;

        return rhsObj;
    }

    // Variation - 3
    //--------------    
    MyClass &operator +(MyClass &rhsObj) {
        this->myInteger = this->myInteger + rhsObj.myInteger;
        this->myDouble = this->myDouble + rhsObj.myDouble;

        return *this;
    }
};


int main() {
    MyClass objOne(10, 10.5);
    MyClass objTwo(20, 20.5);

    MyClass objThree = objOne + objTwo;
}

What should be the case of Assignment Operator (=)? Which variation should it use?

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

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

发布评论

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

评论(5

〃安静 2024-12-21 02:29:56

取决于你需要什么。

首先,关于您的版本 - 显然

  • “变体 - 1”创建新对象,而不触及两个操作数。
  • “Variation - 2”将结果存储在第二个操作数中
  • ,“Variation - 3”将结果存储在“this”中的第一个操作数中。

最有可能的是,Variation - 1 是最优选的。

为什么?因为有副作用。如果您看到这样的表达式:

a = b + c;

无论 abc 的类型是什么,您会怎么想?我认为,abc以及bc的总和code> 未受影响,我的意思是 - 使用旧值。
例如,假设:

a = 5;
b = 6;
c = a + b;

您是否期望 ab 在求和后会变成 11? (如果您选择变体 2 或 3,就会发生这种情况)。当然,您不能int重载operator+,但这只是一个简单直观的示例。


一项性能改进:在您的变体 1 中,而不是

MyClass operator+(MyClass rhsObj)

我会使用

MyClass operator+(const MyClass& rhsObj)

这种方式,您将避免一份额外的副本+您将使用您的代码告诉“客户端”您不会更改 rhsObj根本没有,但只是利用它的价值。

Depends on what you need.

First, about you versions - obviously

  • "Variation - 1" creates new object, without touching the two operands.
  • "Variation - 2" stores the result in the second operand
  • "Variation - 3" stores the result in the first operand in "this".

Most likely, Variation - 1 is the most preferred.

Why? Because of the side effects. If you see an expression like:

a = b + c;

whatever is the type of a, b and c, what you would think? I would think, that a is the sum of b and c AND b and c are untouched, I mean - with the old values.
Suppose, for example:

a = 5;
b = 6;
c = a + b;

Would you expect, that a or b will become 11 after the sum? (which will happen if you chose variation 2 or 3). Of course, you cannot overload operator+ for int, but it's just an easy and intuitive example.


One performance improvement: in your variation 1, instead of

MyClass operator+(MyClass rhsObj)

I would use

MyClass operator+(const MyClass& rhsObj)

This way you'll avoid one additional copy + you will tell the "client", using your code, that you don't change rhsObj at all, but just use its value.

笑看君怀她人 2024-12-21 02:29:56

您确实想要这里的一个三个的变体。

MyClass 的用户希望它遵循最小惊讶原则并且绝不会期望看到右侧因加法而被修改。使用 const more 将强制执行此操作,并且也将用作文档。如果您想修改左侧,请使用+=。像这样:

// Plus: Modify neither the left nor the right
//--------------
MyClass operator +(const MyClass& rhsObj) const
{
    return MyClass(myInteger + rhsObj.myInteger, myDouble + rhsObj.myDouble);
}

// Increment: Modify the left
//--------------
MyClass& operator +=(const MyClass& rhsObj)
{
    myInteger += rhsObj.myInteger;
    myDouble += rhsObj.myDouble;

    return *this;
}

演示:http://ideone.com/8oarA

You really want variations on one and three here.

Users of MyClass will expect it to follow The Principle of Least Astonishment and would never expect to see the right-hand-side modified as a result of addition. Using const more will enforce this and will also serve as documentation. If you wish to modify the left-hand-side, use +=. Like so:

// Plus: Modify neither the left nor the right
//--------------
MyClass operator +(const MyClass& rhsObj) const
{
    return MyClass(myInteger + rhsObj.myInteger, myDouble + rhsObj.myDouble);
}

// Increment: Modify the left
//--------------
MyClass& operator +=(const MyClass& rhsObj)
{
    myInteger += rhsObj.myInteger;
    myDouble += rhsObj.myDouble;

    return *this;
}

Demo: http://ideone.com/8oarA

但可醉心 2024-12-21 02:29:56

这三个 + 之间存在细微差别。

第一个变化:

// Variation - 1
//--------------
MyClass operator+(MyClass rhsObj)
{
    return MyClass(this->myInteger + rhsObj.myInteger, this->myDouble + rhsObj.myDouble);
}

MyClass 的对象作为输入,这意味着 rhsObj 的副本是传递到 + 中,原始对象 rhsObj 保持不变。此覆盖返回一个新创建的 MyClass 对象。

第二种变体:

// Variation - 2
//--------------
MyClass & operator+(MyClass & rhsObj)
{
    rhsObj.myInteger = this->myInteger + rhsObj.myInteger;
    rhsObj.myDouble = this->myDouble + rhsObj.myDouble;

    return rhsObj;
}

rhsObj 的引用作为输入,并在方法中更新 rhsObj

最后一个变体

// Variation - 3
//--------------    
MyClass & operator+(MyClass & rhsObj)
{
    this->myInteger = this->myInteger + rhsObj.myInteger;
    this->myDouble = this->myDouble + rhsObj.myDouble;

    return *this;
}

也采用对 rhsObj 的引用作为参数,但 rhsObj 未在方法内部进行修改。相反,调用 +MyClass 对象会更新。

There are subtle differences between these three +'s

The first variation:

// Variation - 1
//--------------
MyClass operator+(MyClass rhsObj)
{
    return MyClass(this->myInteger + rhsObj.myInteger, this->myDouble + rhsObj.myDouble);
}

takes an object of MyClass as input, which means a copy of rhsObj is passed into the + remaining the original object rhsObj unchanged. This override returns a newly created object of MyClass.

The second variation:

// Variation - 2
//--------------
MyClass & operator+(MyClass & rhsObj)
{
    rhsObj.myInteger = this->myInteger + rhsObj.myInteger;
    rhsObj.myDouble = this->myDouble + rhsObj.myDouble;

    return rhsObj;
}

takes a reference to rhsObj as input and the rhsObj is updated in the method.

The last variation

// Variation - 3
//--------------    
MyClass & operator+(MyClass & rhsObj)
{
    this->myInteger = this->myInteger + rhsObj.myInteger;
    this->myDouble = this->myDouble + rhsObj.myDouble;

    return *this;
}

also takes a reference to rhsObj as parameter, but rhsObj is not modified inside the method. Instead, the MyClass object on which the + is invoked updated.

洒一地阳光 2024-12-21 02:29:56

从概念上讲,您想要返回一对新的,因此在您的情况下,第一个变体可能更好。

或者也许您想返回参数之一,但后来我发现运算符的名称令人困惑。对于第三个变体,+= 可能会更好。

Conceptually, you want to return a new pair, so in your case the first variant is perhaps better.

Or perhaps you want to return one of the argument, but then I find confusing the name of the operator. It could be better += for the third variant.

也只是曾经 2024-12-21 02:29:56

我认为变体 1 最好,主要有一个原因:如果您只有语句 lhs + rhs;,您会期望/想要 lhsrhs< /code> 要修改吗?我知道在大多数(所有?)情况下我可能不会。

因此排除了变体 2 和 3。

I would think variation 1 would be best for mainly one reason: if you had just the statement lhs + rhs;, would you expect/want lhs or rhs to be modified? I know that I probably wouldn't in most (all?) cases.

Therefore that rules out variations 2 and 3.

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