Why friend function is preferred to member function for operator<<

前端 未结 4 804
独厮守ぢ
独厮守ぢ 2021-02-10 06:38

When you are going to print an object, a friend operator<< is used. Can we use member function for operator<< ?

class A {

public:
void operator<         


        
相关标签:
4条回答
  • 2021-02-10 07:14

    You have no choice -- it has to be a free function.

    Note, however, that it need not necessarily be a friend function. It only needs to be a friend if you actually need to grant it private access. For example, I use the following in programming competitions:

    template <class A, class B>
    std::ostream& operator<<(std::ostream& os, const std::pair<A, B>& p)
    {
      return os << '(' << p.first << ", " << p.second << ')';
    }
    

    No need for it to be friend, as first and second are accessible publicly.

    0 讨论(0)
  • 2021-02-10 07:20

    You can't. But If you don't want it to be a friend function, make it a free function and implement it in terms of the class' public interface. For eg.

     ostream& operator<<(ostream& os, Myclass& obj)
    {
       return obj.print(os);
    }
    
    ostream& MyClass::print(ostream& os)
    {
       os << val; // for example.
       return os;
    }
    
    0 讨论(0)
  • 2021-02-10 07:28

    A further reason in your example - it has to be a friend because that's the only way to define a free function inside the class definition. If you wanted a non-friend free function, it would have to be defined outside the class.

    Why would you prefer to define it in the class? Sometimes it's nice to define all the operators together:

    struct SomeClass {
        // blah blah blah
        SomeClass &operator+=(const SomeClass &rhs) {
            // do something
        }
        friend SomeClass operator+(SomeClass lhs, const SomeClass &rhs) {
            lhs += rhs;
            return lhs;
        }
        // blah blah blah
        // several pages later
    };
    

    might be a bit more user-friendly than:

    struct SomeClass {
        // blah blah blah
        SomeClass &operator+=(const SomeClass &rhs) {
            // do something
        }
        // blah blah blah
        // several pages later
    };
    
    SomeClass operator+(SomeClass lhs, const SomeClass &rhs) {
        lhs += rhs;
        return lhs;
    }
    

    This assumes of course that you are defining the related member functions in the class definition, rather that declaring them there and defining them in a .cpp file.

    Edit: I've used += and + as an example without really thinking about it, but your question is about operator<<, which doesn't have any closely related operators like operator+ does. But if operator<< calls one or more member functions related to printing, you might want to define it near where they're defined.

    0 讨论(0)
  • 2021-02-10 07:41

    You have to use a free function and not a member function as for binary operators the left hand side is always *this for member functions with the right hand side being passed as the other parameter.

    For output stream operators the left hand side is always the stream object so if you are streaming to a standard class and not writing the stream yourself you have to provide a free function and not a member of your class.

    Although it would be possible to provide a backwards stream operator as a member function and stream out like this:

    myObject >> std::cout;
    

    not only would you violate a very strong library convention, as you point out, chaining output operations would not work due to the left-to-right grouping of >>.

    Edit: As others have noted, while you have to make it a free function it only needs to be a friend if the streaming function cannot be implemented in terms of the class' public interface.

    0 讨论(0)
提交回复
热议问题