0

Consider the following program:

#include <iostream>
    using namespace std;
     
    class B;
    class A {
        int a;
    public:
        A():a(0) { }
        void show(A& x, B& y);
    };
     
    class B {
    private:
        int b;
    public:
        B():b(0) { }
        friend void A::show(A& x, B& y);
    };
     
    void A::show(A& x, B& y) {
        x.a = 10;
        cout << "A::a=" << x.a << " B::b=" << y.b;
    }
     
    int main() {
        A a;
        B b;
        a.show(a,b);
        return 0;
    }

What confuses me in this question is that inside class A, we haven't declared function show to be friend function of class A. Then how can we use the value x.a (which is private data member of class A) in the definition of show() function?

According to me, show function would have been friend function of class A, had it been defined in this manner:

friend void show(A& x, B& y);

Please guide.

  • `show()` is a member of class `A`, so it has access to all members of all instances of class `A`. `private` members of a class are accessible to all member functions of that class, or to `friend`s of that class. – Peter Jun 28 '21 at 14:48
  • A confusion a lot of new C++ programmers do is to think `private` fields means the members of `this` instance (like in real life). The `private` or `protected` property works *per class* and not *per instance*. – prapin Jun 28 '21 at 17:59

1 Answers1

3

You can access private members in member functions of the same class. A::show is a member of A and can access all members of A.


If that wouldn't be the case, private members would be a big annoyance. Consider this example:

class C {
     int x;
     void foo() {
         x = 42;
     }
};

C has all members private, and foo can access x without the need to befriend them. friend is only for the special case when you want to break encapsulation in a controlled manner when you feel it is appropriate.


Further I suggest you to review the parts in your book that explain member functions. Your show does not use this (the current object), hence it could be a free function (in which case you actually would need to make it a friend to access the private member). Though I think it should rather be:

 void A::show(const B& y) {
    a = 10;
    cout << "A::a=" << a << " B::b=" << y.b;
 }

You also should not assign to the member in a method called show and then the method should be declared const. But one thing at a time, and I didn't want to change your code completely.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • I find it surprising that any textbook or course would cover `friend` before this was explained. – Useless Jun 28 '21 at 14:34
  • Oh, that means, show function is actually a member function of class A, right? – loveofprogramming Jun 28 '21 at 14:34
  • @Useless some thoughts here, but sometimes I decide to write an answer rather than a snarky comment ;) – 463035818_is_not_an_ai Jun 28 '21 at 14:35
  • @loveofprogramming it seems you skipped the section about member access and jumped to the part explaining `friend`. That is unfortunate. Note that making a function or class friend of another should be kept for special cases and only when needed. – 463035818_is_not_an_ai Jun 28 '21 at 14:36
  • Yep, all the functions declared inside the body of your class are member functions (just like data members) ... with the _exception_ of `friend` declarations, which is why they get a special keyword. – Useless Jun 28 '21 at 14:36
  • BTW, `void A::show(A&, B&)` is strange as it doesn't use `this`. `void A::show(B&)` seems better, or indeed `friend void show(A&, B&)` (for both `A` and `B`). – Jarod42 Jun 28 '21 at 14:39