0

What is the difference between creating class P with all members as private and befriending class B which is derived from P

class P
{
private:
        int i;
        friend class B;
};

class B: public P
{
public:
        void get()
        {
                cout <<i;
        }
};

int main()
{

        B obj2;
        obj2.get();
        return 0;
}

vs

Creating a class within a class so that nobody can use the hidden class(subclass) it would be easy for maintanence without having to worry about breaking someone elses dependent code.

In which situation do we choose which design from the above(or any other if any)?

This question is in continuation to the comment section of answer of Why would one use nested classes in C++?

anurag86
  • 1,635
  • 1
  • 16
  • 31
  • "class P [...] befriending class B which is derived from P" sounds like bad design. Could you give an example. – JHBonarius Jun 29 '18 at 06:45
  • @JHBonarius Why not? Imagine a node class with a parent pointer to a derived Group class. – Scheff's Cat Jun 29 '18 at 06:46
  • sure. Let me add – anurag86 Jun 29 '18 at 06:46
  • 3
    "creating class P with all members as private and befriending class B which is derived from P" Then why not make all members protected instead? – Thomas Jun 29 '18 at 06:46
  • Because even though the members are protected it is freely accesible to outside world but the subclass is not. Hence in the latter case, if you need to change the subclass you dont need to worry about breaking others code(if any) – anurag86 Jun 29 '18 at 06:48
  • 2
    @Scheff I think the base class should not be dependent on its derivatives: sounds like a risk for circular dependency. There are other solutions for that. – JHBonarius Jun 29 '18 at 06:49
  • @JHBonarius For a pointer or reference, an incomplete class (forward declaration) is sufficient. (The Node/Group classes are intended for a tree. I didn't find any better solution as a parent of a node _must_ be a group in my example.) – Scheff's Cat Jun 29 '18 at 06:51
  • Are we talking about the same thing? As I understand it, he wants to do `Class P { friend class B; }; Class B : P { };`. – JHBonarius Jun 29 '18 at 06:56
  • @JHBonarius: just declaring friend class B (as shown in the question), would be sufficient and it compiles. dont think there is circular dependency here. – anurag86 Jun 29 '18 at 07:06
  • Is there any *realistic* scenario where such a pattern actually would make sense? All I can think of would be better resolved via B aggregating P instead of inheriting from... – Aconcagua Jun 29 '18 at 08:04
  • @anurag86 - You might also want to read [Can I access private members from outside the class without using friends?](https://stackoverflow.com/questions/424104/can-i-access-private-members-from-outside-the-class-without-using-friends). And the answer is Yes. – Bo Persson Jun 29 '18 at 10:15

1 Answers1

0

Don't do what you suggest: its bad design and there's a chance of circular dependencies. Use protected members instead.

class P
{
protected:
    int i = 42;
};

#include <iostream>

class B : public P
{
public:
    void get()
    {
        std::cout << i << std::endl;
    }
};

int main()
{
    B Bobj;
    Bobj.get();

    std::cin.ignore();
    return 0;
}
JHBonarius
  • 10,824
  • 3
  • 22
  • 41
  • But if you do this someone has a chance to derive from class P which creates dependency because of which there is a chance of breaking his code in case you change P. The same point is discussed in the other thread (link in the question) – anurag86 Jun 29 '18 at 07:15
  • @anurag86 The same can be said for your example. What I suggest here is a base design pattern for C++. It seems your question is an [XY problem](http://xyproblem.info/). What do you *really* want to achieve? – JHBonarius Jun 29 '18 at 07:35