C++ friend inheritance? - c++

Does a subclass inherit, the main class' friend associations (both the main class' own and other classes friended with the main class)?
Or to put it differently, how does inheritance apply to the friend keyword?
To expand:
And if not, is there any way to inherit friendship?
I have followed Jon's suggestion to post up the design problem:
C++ class design questions

Friendship is not inherited in C++.
The standard says (ISO/IEC 14882:2003, section 11.4.8):
Friendship is neither inherited nor transitive.

You can create (static) protected methods in the parent that will allow you to do things like that.
#include <stdio.h>
class MyFriend
{
private:
int m_member = 2;
friend class Father;
};
class Father
{
protected:
static int& getMyFriendMember(MyFriend& io_freind) { return io_freind.m_member; }
};
class Son : public Father
{
public:
int doSomething(MyFriend& io_freind)
{
int friendMember = getMyFriendMember(io_freind);
return friendMember;
}
};
int main(){
MyFriend AFriendOfFathers;
Son aSonOfFathers;
printf("%d\r\n", aSonOfFathers.doSomething(AFriendOfFathers));
return 0;
}
This however bypasses encapsulation so you probably should take a second look at your design.

friend only applies to the class you explicitly make it friend and no other class.
http://www.parashift.com/c++-faq-lite/friends.html#faq-14.4

The answer is very simple: no, subclasses do not inherit friend associations. A friend can only access the private members of the class the association is declared in, not those of parents and/or children of that class. Although you might be access protected member of a superclass, but I'm not sure about that.

Related

C++ allow derived classes of friend to have access to private nested class

Here's what I'm trying to do:
class A
{
friend class C (and all of C's derived classes)
public:
void DoAThing() { mpMyC->DelegateResponsibility(myB); }
private:
class B
{
};
B mMyB;
C* mpMyC;
};
class C
{
// No problem here- C can see B
virtual void DelegateResponsibility(const A::B& necessaryInfo);
};
class D: public C
{
// Uh-oh- we don't inherit friendship
virtual void DelegateResonsibility(const A::B& necessaryInfo);
};
In short, I have a private nested class inside A because it's an implementation detail of A. However, I'd like to delegate some responsibilities of A to C and C's derived classes to get some polymorphic behavior. I'd like to avoid having to add a friend class line every time someone derives from C. The standard workaround given for derived friend classes is "just add a protected accessor function to your base class and override it for derived members" but that only helps access private members of class A, not privately scoped classes. Is there any way to workaround this issue?
This should work:
class C
{
typedef A::B MyB;
virtual void DelegateResponsibility(const MyB& necessaryInfo);
};
class D: public C
{
// Uh-oh- we don't inherit friendship
virtual void DelegateResonsibility(const MyB& necessaryInfo);
};
You could put your class B in a detail namespace, at file scope.
something like this:
namespace my_hidden_area {
class B {
...
}
}
It's not as strong protection as making the class nested private, of course, but it should make it clear to outsiders that they should not be messing around with B.
If you're wondering why friendship is not inheritable, see this question: Why does C++ not allow inherited friendship?

Calling a protected method for a member object in C++

If i have two classes, for example like this
class A {
...
protected:
B* test;
aFunction();
};
class B {
...
protected:
A* test1;
public:
bFunction();
};
can I do this inside bFunction() of class B:
bFunction(){
test1->aFunction();
}
Basically, can I call a protected function of a certain class from the class that's not derived from that function?
The "point" of the protected is that only classes that are derived from the baseclass can call those functions.
If you have a good reason to do this, then make the class a friend, e.g. add friend class B; inside class A.
It is recommended to avoid such inevident mutual dependencies. A necessity to use friend functions often indicates bad architecture.
From cplusplus.com:
Private and protected members of a class cannot be accessed from
outside the same class in which they are declared. However, this rules
does not affect friends.
You can call protected and privat methods from other classes, when those are 'friends':
In your case that would be:
Class A {
...
protected:
B* test;
aFunction();
friend class B;
}
Often that is considered bad practice, but for tightly coupled classes that is ok.

Understanding member access with inheritance / friend class in C++

from C++ primer 5th edition:
have a look at these classes:
class Base {
friend class Pal;
public:
void pub_mem();
protected:
int prot_mem;
private:
int priv_mem;
};
class Sneaky : public Base {
private:
int j;
};
class Pal {
public:
int f1(Base b){
return b.prot_mem; //OK, Pal is friend class
}
int f2(Sneaky s){
return s.j; //error: Pal not friend, j is private
}
int f3(Sneaky s){
return s.prot_mem; //ok Pal is friend
}
}
Here Pal is a friend class of Base, while Sneaky inherits from Base and is used in Pal.
Now the very last line where s.prot_mem is invoked, author gives the reason it works because Pal is a friend class of Base. But what i read so far, my understanding tells me that it should work anywawy, because s derives from Base and prot_mem is protected member of Base Class, which should have already access to Sneaky, can you explain why i am wrong or some more elaboration please?
my understanding tells me that it should work anyway, because s
derives from Base and prot_mem is protected member of Base Class,
which should have already access to Sneaky
No, protected variable prot_mem can only be accessed by derived class member, but not by third party class member, like class Pal, if Pal is not a friend of Base.
Without friendship, Pal only sees Sneaky or Base's public members. The fact that one member of Base is protected does not benefit Pal in any way - it only benefits Sneaky.
The thing is that while Sneaky can access prot_mem, the code you're showing is not in Sneaky, it's in Pal. If Pal was an unrelated class, it couldn't access prot_mem, which is also protected in Sneaky. However, Pal is a friend of Base, which gives it the access necessary.

friendship: many classes from same parent

How can I reach privateMember without friend in all of the derived classes?
class parent{...}; //a virtual class
class A: public parent{...};
class B: public parent{...};
class C: public parent{...};
class D: public parent{...};
class E: public parent{...};
...
//each has a function, that want access to privateMember
class MyClass{
int privateMember;
friend parent;
//I know it doesnt't work, but this shows the best what I want
}
Leave it as is (with friend class parent) and add an accessor function to parent that A, B,... will use. It would be protected, so functions from outside the hierarchy can't use it.
class parent {
protected:
static int& getPrivate( MyClass & c ) { return c.privateMember; }
...
};
You have to do this, because friendship doesn't extend to derived classes.
You could create a getter function, that would return a privateMember:
int getPrivateMember() const { return privateMEmber; }
This must be a public method of course.
The simple answer here is to not go mucking with the internal state of other classes. Instead, use their public API. This way you never have to worry about locking yourself into an implementation AND you avoid a wide variety of potential problems with inadvertently breaking class invariants when you modify the variable.

Becoming a friend through Inheritance C++

Lets say I have two classes
Widget
^
|
Window
and I have another class Application:
Defined as follows
class Application
{
public:
...
private:
friend Widget;
};
This will not give Window access to Applications protected and private members. Is there a way to accomplish this without declaring Window and any subsequent "Widget" as a friend of Application?
No it is not possible.
friendship is not inheritable.
Also, friendship indicates a intentional strong coupling between two entities So if your design indeed demands such a strong coupling go ahead and make them friends. friendship breaking encapsulation is a far too misunderstood concept.
Would defining some methods in the base class to forward calls to Application do the job?
Eg.
class Application
{
public:
...
private:
friend Widget;
void PrivateMethod1();
};
class Widget
{
protected:
void ApplicationPrivateMethod1() { /* forward call to application.PrivateMethod1(); */ }
};
class Window : Widget
{
void SomeMethod()
{
// Access a friend method through the forwarding method in the base Widget class
ApplicationPrivateMethod1();
}
};
If the inherited methods are the only ones that need access to app class than you can declare the individual methods as friends and as long as the window class doesn't override them they can use those methods with friend access.