Class 数据的重载 + 运算符

Overload + Operator for Class Data

假设我有以下基本的class,我想在其中重载运算符+:

class foo {
private:
    arbitrary datatype

public:
    foo() { set private data; };
    virtual ~foo() {};

};

我一直使用这种格式:

foo operator+( const foo &rhs );

但是,我最近偶然发现了一些人专门使用的代码:

friend foo operator+( const foo &lhs, const foo &rhs );

那么,使用一个版本而不是另一个版本是标准的吗?在某些情况下,您是否会被迫进入一个版本(这仅用于添加相同的对象类型)?我不熟悉汇编语言,但是编译器会把它们转换成相同的指令列表吗(这个问题显然取决于前两个问题的答案)?

  1. 回答您的前 2 个问题

    建议(但不强制)对二元运算符使用 friend 方法,因为它允许在运算符的左侧有可转换为 class 的对象。考虑一下:

    class Foo
    {
        // private members
    public:
        Foo(int) {/* ctor implementation */} // implicit convertible to int
        Foo(const Foo&) { /* copy ctor implementation */ }
        friend Foo operator+(const Foo& lhs, const Foo& rhs){/* implementation */}
    };
    

    现在您可以:

    Foo foo1{1};
    Foo foo2 = 1 + foo1; // 1 is implicitly converted to Foo here
    

    如果operator+是一个成员函数,上面的调用就会失败(左边,即使可以转换为Foo,也不会被编译器自动转换),你只能使用

    Foo foo2 = foo1 + 1;
    

    因此,总而言之,对二元运算符使用 friend 使它们更 "symmetric"。

  2. 最后一题:

    汇编器不会生成相同的代码,因为 friend/member operator+ 做的事情略有不同。

另请参阅关于重载运算符的非常很好的指南here