开发者

C++ how to write an operator that isn't a member function?

开发者 https://www.devze.com 2023-03-18 08:35 出处:网络
Anyone got an idea on how to write an operator for a class that isn\'t a member function of the 开发者_如何学Goclass?Just make it a free function, or a friend function. A good example of this is opera

Anyone got an idea on how to write an operator for a class that isn't a member function of the 开发者_如何学Goclass?


Just make it a free function, or a friend function. A good example of this is operator<<:

class X {
    public:
    int x; 
}

ostream& operator<< (ostream& os, const X& x) {
    os << x.x;
    return os;
}

The benefit of making it a friend function is that you have direct access to private members, whereas a free function must access all members via public methods.


Arithmetic operators, stream operators, et cetera are often not members of a class. However, they may need to be friends in order to access private data members.

I prefer not to use friend and to expose methods that can be used by the operators instead. I believe this to be more in keeping with the Open/closed principle, as I could easily add a subtraction operator without editing the class.

These are handy for unit-testing, too (I can "inject" a std::ostringstream to test the output of print(), for instance).

Here is an example:

#include <iostream>

class Number
{
public:
    Number(int j)
        :i(j)
    {
    }

    void print(std::ostream& os) const
    {
        os << i;
    }

    int value() const
    {
        return i;
    }
private:
    int i;
};

std::ostream& operator <<(std::ostream& os, const Number& n)
{
    n.print(os);
    return os;
}

Number operator +(const Number& n, const Number& o)
{
    return Number(n.value() + o.value());
}

int main()
{
    Number a(4), b(5), c(a + b);
    std::cerr << c << std::endl;
}


Just declare the global function with the operator name:

Point operator+(Point& p, Vector& v) {
    return new Point(p.x + q.i, p.y + q.j);
}


Basically, you can take the operator out of the class, and add a parameter to the beginning of the parameter list. In many cases, you will also need to declare the operator function as a friend.

For instance

class Foo
{
    Foo operator +( Foo const& other );
};

becomes

class Foo
{
    friend Foo operator +( Foo const&, Foo const& );
};

Foo operator +( Foo const& first, Foo const& second );

The friend statement allows the operator to still access any private or protected members needed.

Note that there are some restrictions on which operators can be overloaded in this manner. See this article for such a list.

0

精彩评论

暂无评论...
验证码 换一张
取 消