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.
Related
class foo
{
bar b;
someFunction()
{
b.alphaObj->someFunctionOfAlpha();
}
};
class bar
{
friend class foo;
// many more friends
private:
alpha *alphaObj;
};
How do I remove the friend dependency without exposing the private members with getters and setters.
I understand friend classes could help in enhancing encapsulation but there are a lot of friend classes defined in my class exposing the private members to all. Hence I am thinking of a better approach and any help is appreciated.
Independent of your friend issue, being required to write this
b.alphaObj->someFunctionOfAlpha();
is not the best design. You should rather call (*):
b.someFunctionOfAlpha();
Now it is also obvious how to remove the friends:
class bar
{
public:
void someFunctionOfAlpha() { alphaObj->someFunctionOfAlpha(); }
private:
alpha *alphaObj;
};
(*) This guideline has a name, I just cannot find it at the moment. In general, calling a method should be like: "Do that!". Calling a method should not be like "Show me your internals so I can do what I want".
How can ensure that only "my" code can use a class, even if it is used a base class? (If it's not used as a base class I can make it a private or protected nested class of one of my classes)
If I want to indicate that use of a base class for one of my classes is a mere implementation detail, I can use a private base class:
class Base
{
...
}
class Derived: private Base
{
public:
Derived(...): Base{...} {... };
...
}
To clients of my Derived class, that I used the Base class is not apparent:
#include "Derived.h"
void client() {
Derived d{...};
Base *b = static_cast< Base * >(&d);// error
...
}
But imagine that the Base class is so specialised, or confusing, or tricky to use, that I don't want it to be possible for clients of my code to use it as a base class or create objects of that class. I want it to be "private", in some sense, to some of my code, so client code like this fails:
#include "Derived.h"
class Client: Base// error wanted here
{
public:
Client(...): Base{...} {...};
...
}
void client()
{
Derived d{...};// OK
Base b{...};// error wanted here
Client c{...};// error wanted here
}
How can I do that?
In effect, I am asking how can I achieve something like Java's package-private classes, which are accessible to only other classes in the same "package" (module), but can not be used by code outside the "package".
You can "enforce" this by convention, by placing the "private" entities into a detail namespaces. Many popular libraries (e.g. Boost) do this:
namespace detail
{
class Base { /* ... */ };
}
class Derived : private detail::Base
{
/* ... */
};
When modules will be standardized this problem will be solved properly, as you will be able to control what entities get exported and which ones are implementation details.
This can't be done directly as you would do in Java. If it's only a matter of avoiding confusion you can move Base inside a namespace which is meant to be ignored by clients of your code, eg:
namespace hidden {
class Base {
..
};
}
class Derived : private hidden::Base {
...
};
If instead you really want to avoid the possibility of using Base then it's quite a difficult story if you plan to use Base as a parent of multiple classes (which amount could vary over time). You could give Base a private constructor, and indicate that each of your derived classes is a friend of Base:
class Hider {
private:
Hider() = delete;
class Base {
..
};
friend class Derived;
};
class Derived : Hider::Base {
..
};
Of course this requires manual maintenance for each new class you want to derive from Base.
If you want to enforce it 100%, and don't like the python method of" please don't use things that start with '_'" then I believe this is your port of call:
class Dave;
class MyPrivateBaseClasses {
private:
MyPrivateBaseClasses(); // ensure nothing can use this class
class BaseClassA {};
friend Dave;
};
class Dave : public/private MyPrivateBaseClasses::BaseClassA
{};
Sure - it means you have to friend everything that wants to use it, but it does give you exactly what you wanted; 100% protection against people using BaseClassA.
I have the following typical scenario, in which I want to hide implementation details in a child class, and expose it through an interface:
template <typename Derived>
class Interface
{
public:
void a()
{
static_cast<Derived*>(this)->_a();
}
};
class Implementation : public Interface<Implementation>
{
protected:
void _a()
{
/*
...
*/
}
};
I think I understand why this doesn't work, and I know that declaring the class Interface as friend of Implementation solves it, but when it comes to more complex hierarchies, like multiple interfaces, and various levels of inheritance(as is my real case), things get really messy.
I would like to avoid having to declare friend class Interface<Implementation> in each class that implements an interface.
Is there an alternative nice-and-clean solution for this problem?
Thanks!
How about using virtual functions and polymorphism?
Create an object in your child class and reassign it to an interface class pointer or reference. Then create a pure virtual function in your interface class and define it in your child class.
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.
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.