Home > Net >  How to not use friend declaration when equipping a class with `operator<<`
How to not use friend declaration when equipping a class with `operator<<`

Time:05-10

I understand that we'd want to do something like this to override operator<<

#include <iostream>

class Point
{
private:
    double m_x{};
    double m_y{};
    double m_z{};

public:
    Point(double x=0.0, double y=0.0, double z=0.0)
      : m_x{x}, m_y{y}, m_z{z}
    {
    }

    friend std::ostream& operator<< (std::ostream& out, const Point& point);
};

std::ostream& operator<< (std::ostream& out, const Point& point)
{
    // Since operator<< is a friend of the Point class, we can access Point's members directly.
    out << "Point(" << point.m_x << ", " << point.m_y << ", " << point.m_z << ')'; // actual output done here

    return out; // return std::ostream so we can chain calls to operator<<
}

int main()
{
    const Point point1{2.0, 3.0, 4.0};

    std::cout << point1 << '\n';

    return 0;
}

source: https://www.learncpp.com/cpp-tutorial/overloading-the-io-operators/

But what if I don't need to access private member variables? I could continue to use friend but I'd prefer not to as in my opinion that would be confusing code. But I couldn't figure out how to not use friend. I tried:

  1. Just dropping friend, but then the compiler would insert the implicit this pointer as the first argument, which is not what I want.
  2. Changing friend to static, but my IDE complains that operator<< cannot be static.

CodePudding user response:

You can just declare operator<< as a free function in the same namespace as Point (in this case, the global namespace) and ADL will take care of it:

#include <iostream>

class Point {
   private:
    double m_x{};
    double m_y{};
    double m_z{};

   public:
    Point(double x = 0.0, double y = 0.0, double z = 0.0)
        : m_x{x}, m_y{y}, m_z{z} {}

};

std::ostream& operator<<(std::ostream& out, const Point& point) {
    out << "Point";
    // Use public interface of point here.
    return out;
}

int main() {
    const Point point1{2.0, 3.0, 4.0};

    std::cout << point1 << '\n';

    return 0;
}

CodePudding user response:

Same example, less code:

class Point
{
    friend std::ostream& operator<< (std::ostream& out, const Point& point);  // 1
};


// 2
std::ostream& operator<< (std::ostream& out, const Point& point)
{    
    return out;
}

//1 is just declaring that std::ostream& operator<<(std::ostream&,const Point&); is a friend of the class. Thats all this line means. If you do not want to declare the function as a friend of the class then remove this line:

class Point {};


std::ostream& operator<< (std::ostream& out, const Point& point)
{
    // only access to public members of point
    return out;
}

CodePudding user response:

Three ways to solve this:

  1. make m_x, m_y, m_z public
  2. add public x, y, z methods that return m_x, m_y, m_z
  3. add public print method that the operator << can call
  •  Tags:  
  • c
  • Related