Operator overloading inside vs outside class

This question already has an answer here:

  • Operator overloading outside class [duplicate] 3 answers
  • What are the basic rules and idioms for operator overloading? 7 answers

  • First consider this example using your class (reformatted to a style I prefer):

    class A
    {
    public:
        auto operator==( A const* p )
            -> bool
        {
            return true;        // Whatever.
        }
    };
    
    auto main()
        -> int
    {
        A u{}, v{};
        A const c{};
    
        bool const r1 = (u == &v);  // OK but needlessly annoying.
        bool const r2 = (c == &v);  // !Will not compile. 
    }
    

    Here

  • Since the argument is a pointer, the client code must apply & .
  • Since the method is not const , objects that are const can not be compared.
  • The conventional way to do this is therefore to pass the argument by reference, and to make the method const :

    class B
    {
    public:
        auto operator==( B const& o ) const
            -> bool
        {
            return true;        // Whatever.
        }
    };
    
    auto main()
        -> int
    {
        B u{}, v{};
        B const c{};
    
        bool const r1 = (u == v);   // OK.
        bool const r2 = (c == v);   // OK.
    }
    

    If you define the comparison outside the class, like this:

    class B
    {};
    
    auto operator==( B const& u, B const& v )
        -> bool
    {
        return true;        // Whatever.
    }
    
    auto main()
        -> int
    {
        B u{}, v{};
        B const c{};
    
        bool const r1 = (u == v);   // OK.
        bool const r2 = (c == v);   // OK.
    }
    

    … then

  • The definition guaranteed does not depend on internal implementation details of class B , that conceivably could change in the future.
  • Also the first argument can be a value that converts implicitly to B .
  • You can, if you want, have formal arguments of different types, where the class only appears in the second argument, like this:
  • auto operator==( int const u, B const& v )
        -> bool
    {
        return true;        // Whatever.
    }
    

    If you choose to place these non-member operators inline inside the class definition, via the friend mechanism (so that they're found via ADL lookup), then you lose the first bullet point's advantage, but you then have all the code relevant for use of the class, within the class definition:

    class B
    {
    public:
        friend
        auto operator==( B const& u, B const& v )
            -> bool
        {
            return true;        // Whatever.
        }
    
        friend
        auto operator==( int const u, B const& v )
            -> bool
        {
            return true;        // Whatever.
        }
    };
    
    auto main()
        -> int
    {
        B u{}, v{};
        B const c{};
    
        bool const r1 = (u == v);   // OK.
        bool const r2 = (c == v);   // OK.
        bool const r3 = (42 == v);  // OK.
    }
    
    链接地址: http://www.djcxy.com/p/12716.html

    上一篇: 运算符重载“float”和“<<”

    下一篇: 内部操作符与外部类重载