1

Why can't I access private functions of class Box in ostream& operator<<(ostream& out, const Box& B){cout << B.l << " " << B.b << " " << B.h << endl; }?

#include<bits/stdc++.h>
using namespace std;

class Box{
    int l, b, h;
    public:
      Box(){
          l=0;
          b=0;
          h=0;
      }
      Box(int length, int breadth, int height){
          l=length;
          b=breadth;
          h=height;
      }
      bool operator < (Box &B){
          if(l < B.l)return 1;
          else if(b < B.b && l==B.l)return 1;   
          else if(h< B.h && b== B.b && l==B.l)return 1;
          else return 0;
      }

    };
    ostream& operator <<(ostream& out, const Box& B){
        cout << B.l << " " << B.b << " " << B.h ;
        return out;
    }
  • 1
    Since the purpose of `private` is to restrict access, you should add an explanation of why you think access should be allowed in this case. – JaMiT Jun 16 '22 at 05:14
  • The `operator<<()` function is not a member of class `Box`. To access `private` members of a `Box`, there needs to be a `friend` declaration (e.g. `friend std::ostream &operator<<(std::ostream &, const Box &);` within the definition of `Box`). Also, it is inadvisable to rely on `using namespace std` in cases like this, since it can introduce ambiguity in some situations - instead use the fully qualified name `std::ostream` rather than `ostream`. – Peter Jun 16 '22 at 11:28
  • Ask yourself whether it really makes sense that `operator<<` specifically, but not other functions, should be able to access the members. My feeling is that `Box` should probably have getter functions to retrieve the values for all three. Or should it really be impossible to figure out what e.g. the length of a `Box` is? `operator<<` can then simply use the public interface. – user17732522 Jun 20 '22 at 17:55
  • actually, I used the getter functions in the original program and the public interface. my question should be does ostream& makes any difference. the issue was resolved by making them freind. – suraj patil Jun 20 '22 at 18:57

2 Answers2

1

The problem is that you don't have any friend declaration for the overloaded operator<< and since l, b and h are private they can't be accessed from inside the overloaded operator<<.

To solve this you can just provide a friend declaration for operator<< as shown below:

class Box{
    int l, b, h;
    //other code here as before
    
//--vvvvvv----------------------------------------->friend declaration added here
    friend ostream& operator <<(ostream& out, const Box& B);

};
//definition same as before
ostream& operator <<(ostream& out, const Box& B){
    cout << B.l << " " << B.b << " " << B.h ;
    return out;
}

Working demo

Jason
  • 36,170
  • 5
  • 26
  • 60
1

You can implement the operator overloading in two ways:

  1. Member function

    If it is a member function, then any instance of Box, can access the private members of Box class.

    For e.g., for operator "bool operator < (Box& b)", when you call b1 < b2 (where b1 and b2 are instances of Box), then you can directly access private members of both b1 and b2 in the "operator <" implementation.

  2. Non-member function

    Non-member functions, by default, cannot access the privates of a class.

    So, either the non-member overloaded operator has to be declared as a friend of Box class or you need to define public functions for the private members which will be accessed in this non-member overloaded operator.

You can also check the discussion here, which clearly explains when an overloaded operator can be implemented either as a member or a non-member function: Operator overloading : member function vs. non-member function?

Manjunath Ballur
  • 6,287
  • 3
  • 37
  • 48