在C ++中重载运算符+和- [英] Overloading operators + and - in C++

查看:69
本文介绍了在C ++中重载运算符+和-的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个关于超载的问题.

I have two questions about overloading.

1-为什么有时使重载运算符成为非成员函数?

1- Why sometimes do make overloading operators non-member functions?

friend Class operator-(const Class &rhs);

2-之间有什么区别

Class operator+(const Class &c1, const Class &c2);

Class operator+(const Class &rhs);

如果我想添加两个对象C3 = C1 + C2?

if I want to add two objects C3 = C1 + C2?

感谢您的帮助...

推荐答案

如果将二进制运算符作为成员函数重载,则结果将不对称地结束:左操作数必须是要重载该运算符的确切类型,但是正确的操作数可以是可以转换为正确类型的任何东西.

If you overload a binary operator as a member function, it ends up asymmetrical: the left operand must be the exact type for which the operator is overloaded, but the right operand can be anything that can be converted to the correct type.

如果使用非成员函数使运算符重载,则可以将两个操作数转换为正确的类型.

If you overload the operator with a non-member function, then both operands can be converted to get the correct type.

第二点所具有的内容看起来像是同一点的具体示例,一点都没有.这是我正在谈论的具体示例:

What you have as your second point looks like a concrete example of the same point, not really anything separate at all. Here's a concrete example of what I'm talking about:

class Integer {
    int val;
public:
    Integer(int i) : val(i) {}
    operator int() { return val; }

    // Integer operator+(Integer const &other) const { return Integer(val + other.val); }

    friend Integer operator+(Integer const &a, Integer const &b) { 
        return Integer(a.val + b.val);
    }
};


int main() { 
    Integer x(1);

    Integer y = x + 2; // works with either operator overload because x is already an Integer

    Integer z = 2 + x; // works with global overload, but not member overload because 2 isn't an Integer, but can be converted to an Integer.
    return 0;
}

还要注意,即使friend函数的定义在Integer的类定义中,但将其声明为朋友这一事实意味着它不是 成员函数-声明friend使其成为全局函数,而不是成员.

Also note that even though the definition of the friend function is inside the class definition for Integer, the fact that it's declared as a friend means it's not a member function -- declaring it as friend makes it a global function, not a member.

最重要的是:这样的重载通常应该作为自由函数而不是成员函数来完成.为用户提供可以正确(剧烈地)工作的操作员,胜过诸如更多面向对象"之类的理论考虑.必要时(例如,当操作员的实现需要虚拟时),您可以执行两步操作,其中提供一个(可能是虚拟的)成员函数来完成实际工作,而重载本身是一个自由函数,它可以在其左侧操作数上调用该成员函数.一个相当普遍的例子是operator<<对于层次结构的重载:

Bottom line: such overloads should usually be done as free functions, not member functions. Providing the user with an operator that works correctly (drastically) outweighs theoretical considerations like "more object oriented". When necessary, such as when the implementation of the operator needs to be virtual, you can do a two-step version, where you provide a (possibly virtual) member function that does the real work, but the overload itself is a free function that invokes that member function on its left operand. One fairly common example of this is overloading operator<< for a hierarchy:

class base { 
    int x;
public:
    std::ostream &write(std::ostream &os) const { 
        return os << x;
    }
};

class derived : public base { 
    int y;
public:
    std::ostream &write(std::ostream &os) const { 
        return (base::write(os) << y);
    }
};

std::ostream &operator<<(std::ostream &os, base const &b) {
    return b.write(os);
}

这既支持多态实现(并在必要时访问基类的受保护成员),而无需放弃运算符的正常特性来获取它.

This supports both polymorphic implementation (and access to a base class' protected members, if necessary) without giving up the normal characteristics of the operator to get it.

将二进制运算符重载为自由函数的主要例外是赋值运算符(operator=operator+=operator-=operator*=等).转换将产生一个临时对象,无论如何您都不能将其分配给它,因此对于这种特殊情况,重载应该(实际上必须是)一个成员函数代替.

The primary exceptions to overloading binary operators as free functions are assignment operators (operator=, operator+=, operator-=, operator*= and so on). A conversion would produce a temporary object, which you can't assign to anyway, so for this particular case, the overload should be (must be, as a matter of fact) a member function instead.

这篇关于在C ++中重载运算符+和-的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆