Although class friendship is one of the last resorts of C++, does this pattern make sense?
class Peer
{
public:
friend class Peer;
void GetSecret(const Peer& other)
{
const std::string& secret = other.GiveSecret();
std::cout << secret << std::endl;
}
private:
const std::string& GiveSecret() const
{
return "secrety stuff";
}
};
int main(int argc, char* argv[])
{
Peer peerA;
Peer peerB;
peerA.GetSecret(peerB);
return 0;
}
Ok the reason for this pattern is because the Peers are all of the same rank, and they need to share knowledge among each other, however this knowledge is secret, because no one but the peers should use it, or the program is no longer valid.
One very real example of this is that when one peer is copy-constructed from another peer it needs to access secret information from its source peer, but again there is no reason for anyone else to know about these internals, just the peers.
friend is not necessary in this case. An object of a class can access the private members of any other object of the same type. It should work just fine without the friend declaration.
standard c++ says that the private clause has class scope. That's means that every Peer can access the private part of any other Peer. This isn't implementation specific
Although you have discovered that friendship is not needed in this case, I'll just say that contrary to the above opions there is nothing wrong in principle with friendship between cooperating class. In fact rather than breaking encapsulation the friendship might actually promotes it.
Consider the alternative where you create an accessor method to your private data. If you do that then you're effectively giving access to the private data of all clients not just the limited set of classes/functions declared as friends. If only one method in your friend class is going to access your internals encapsulation has decreased by exactly the same amount as if you had provided a public accessor method. However, the result of giving a public accessor method will be that far more clients will use method.
For each application class we write there is a shadow class which is the classes unit test. The unit test class is a friend of the application class as it frequently needs to invoke the methods on the class and then examine the class internals, or invoke private methods. By being a friend class encapsulation is maintained.
Anyway for a good discussion see here:
http://www.ddj.com/cpp/184401197
Now that I've said my piece on inheritance, here's something that might help with your real question, i.e. how to get around the potential problems with friendship.
The way I do this is to create a pure interface for accessing data I want to share with my "friends". I then implement this interface privately, so nobody can access it directly. Finally I have some mechanism that allows me to pass a reference to the interface only to those select classes that I want to allow.
For example:
// This class defines an interface that allows selected classes to
// manipulate otherwise private data.
class SharedData
{
public:
// Set some shared data.
virtual void SettorA(int value) = 0;
// Get some shared data.
virtual bool GettorB(void) const;
};
// This class does something with the otherwise private data.
class Worker
{
public:
void DoSomething(SharedData & data)
{
if (data.GettorB() == true)
{
data.SettorA(m_id);
}
}
private:
int m_id;
};
// This class provides access to its otherwise private data to
// specifically selected classes. In this example the classes
// are selected through a call to the Dispatch method, but there
// are other ways this selection can be made without using the
// friend keyword.
class Dispatcher
: private SharedData
{
public:
// Get the worker to do something with the otherwise private data.
void Dispatch(Worker & worker)
{
worker.DoSomething(*this);
}
private:
// Set some shared data.
virtual void SettorA(int value)
{
m_A = value;
}
// Get some shared data.
virtual bool GettorB(void) const
{
return (m_B);
}
int m_A;
bool m_B;
};
In this example, the SharedData is an interface that determines what can be done with the data, i.e. what can be set, and what is get-only. The Worker is a class that is allowed access to this special interface. The Dispatcher implements the interface privately, so having access to a Dispatcher instance doesn't give you access to the special shared data, but the Dispatcher has a method that lets Workers get access.
Not healthy, it breaks the the encapsulation best practice
does this pattern make sense
Not much. Can you elaborate?
You create friendship typically among different classes. This is syntactically valid. Why would Peer be a friend of Peer?
Private functions can only be used by member functions. Calling them from client code is wrong.
As to the question if friendship breaks encapsulation or not, have a look at the FAQ.
Sorry Robert, misread the names.
Not healthy, it breaks the the encapsulation best practice
Well, yes and no.
It can only break encapsulation if you do not use methods to access the data you need.
Not to say that encapsulation is only a way to protect foreign classes to have to be rewritten in case you change implementation details. If you happen to change the implementation, you'll have to rework your class anyway.
First I want to say that with inheritance, a good class hierarchy does not need to expose private data in order for things such as copy constructors or operator overloads to work. For example:
class Sub
: public Base
{
public:
Sub(const std::string & name)
: Base(),
m_name(name)
{
}
Sub(const Sub & src)
: Base(src),
m_id(src.m_name)
{
}
Sub & operator=(const Sub & rhs)
{
if (&rhs != this)
{
Base::operator=(rhs);
m_name = rhs.m_name;
}
return (this);
}
protected:
virtual Debug(void)
{
std::cout << "Sub [m_name = " << m_name << "]" << std::endl
<< "+- ";
Base::Debug();
}
private:
std::string m_name;
};
class Base
{
public:
Base(int id)
: m_id(id)
{
}
Base(const Base & src)
: m_id(src.m_id)
{
}
Base & operator=(const Base & rhs)
{
if (&rhs != this)
{
m_id = rhs.m_id;
}
return (this);
}
protected:
virtual Debug(void)
{
std::cout << "Base [m_id = " << m_id << "]" << std::endl;
}
private:
int m_id;
};
In this example, the subclass is able to instantiate its base members in both the copy constructor and the assignment operator. Even the overly contrived Debug method works without ever having access to the private members of the base class.
Related
I've coded a crossover method for a genetic algorithm (see https://en.wikipedia.org/wiki/Crossover_(genetic_algorithm)).
The crossover method modifies the private members of the Chromosome class but I pulled it out of Chromosome into a separate pure virtual base class CrossoverStrategy (friend of Chromosome) to keep each crossover method nicely encapsulated in a subclass, i.e. the GoF strategy pattern (see https://en.wikipedia.org/wiki/Strategy_pattern).
Now the problem is CrossoverStrategy subclasses can't access Chromosome private members because friendship isn't inherited in C++. The only 2 solutions I see are:
1) Add accessor methods to the pure virtual base class e.g. CrossoverStrategy::getGenes() to make Chromosome private members accessible to subclasses. Because CrossoverStrategy can't anticipate all the stuff its subclasses may want to do with Chromosome, I need to expose everything up front. Ugly!
2) Forward declare each CrossoverStrategy subclass and explicitly make it a friend of Chromosome. This feels slightly less ugly, at least keeps the interfaces and code cleaner. I'm leaning towards this option for aesthetics.
Any better design suggestions? Code below.
// Chromosome.h ++++++++++++++++++++++++++++++++++++++++++++++++
class CrossoverStrategy
{
public:
virtual std::vector<Chromosome*> crossover(Chromosome *parent1, Chromosome *parent2) = 0;
const std::vector<double> &getGenes(Chromosome *instance) { return instance != NULL ? instance->m_genes : std::vector<double>(); }; // OPTION #1 ... BOO! UGLY!
};
class CrossoverStrategyExample1; // OPTION #2 ... BOO! UGLY!
class Chromosome
{
public:
// Friends
friend class CrossoverStrategy;
friend class CrossoverStrategyExample1; // OPTION #2 ... BOO! UGLY!
private:
std::vector<double> m_genes;
};
// CrossoverStrategies.h ++++++++++++++++++++++++++++++++++++++++++++++++
#include "Chromosome.h"
class CrossoverStrategyExample1 : public CrossoverStrategy
{
public:
virtual std::vector<Chromosome*> crossover(Chromosome *parent1, Chromosome *parent2);
private:
};
// CrossoverStrategies.cpp ++++++++++++++++++++++++++++++++++++++++++++++++
#include "CrossoverStrategies.h"
std::vector<Chromosome*> CrossoverStrategyExample1::crossover(Chromosome *parent1, Chromosome *parent2)
{
// Do something with Chromosome private members
// PROBLEM ... m_genes not accessible to subclasses? BOO BOO BOO!
(for unsigned long i = 0; i < parent1->m_genes.size(); i++)
parent1->m_genes[i] = 0.0;
}
Option 2 should be rejected because it does not scale. You will be continually modifying Chromosome to keep it up to date with new CrossoverStrategies.
Option 1 is a strange idea because it places the getter function for Chromosome's data members outside of Chromosome. I can see some cases where this is an attractive idea, if getGenes is made protected, but I'm not convinced here. Consider instead
Option 1-A
class Chromosome
{
public:
const std::vector<double>& getGenes() const
{
return m_genes;
}
private:
std::vector<double> m_genes;
};
Everyone who can access a Chromosome can access getGenes, but they can't do anything to damage it and Chromosome remains blissfully ignorant of its users.
Option 3: Use The Pimpl Idiom
Short and stupid example with a few flaws to keep the demo short
Chromosome.h ++++++++++++++++++++++++++++++++++++++++++++++++
#include <vector>
class Chromosome; // forward declaration only
class CrossoverStrategy
{
public:
virtual ~CrossoverStrategy() = default;
virtual std::vector<Chromosome*> crossover(Chromosome *parent1, Chromosome *parent2) = 0;
};
Chromosome * ChromosomeFactory(/* some construction parameters here */);
// should also provide a declaration of a factory function to provide CrossoverStrategies
CrossoverStrategies.h ++++++++++++++++++++++++++++++++++++++++++++++++
#include "Chromosome.h"
class CrossoverStrategyExample1 : public CrossoverStrategy
{
public:
virtual std::vector<Chromosome*> crossover(Chromosome *parent1, Chromosome *parent2);
private:
};
CrossoverStrategies.cpp ++++++++++++++++++++++++++++++++++++++++++++++++
#include "CrossoverStrategies.h"
class Chromosome
{
public:
std::vector<double> m_genes;
// silence a warning
Chromosome(): m_genes{}
{
}
};
// Because Chromosome is only defined in this file, only this file can use the internals
// of Chromosome. They are public, but the outside world doesn't know that
Chromosome * ChromosomeFactory(/* some construction parameters here */)
{
// Probably makes and returns a pointer to a Chromosome,
// but could pull it from a list, copy construct from a template, etc...
return new Chromosome(/* some construction parameters here */);
}
// should also provide a definition of a factory function to provide CrossoverStrategies
std::vector<Chromosome*> CrossoverStrategyExample1::crossover(Chromosome *parent1,
Chromosome *parent2)
{
for (unsigned long i = 0; i < parent1->m_genes.size(); i++)
parent1->m_genes[i] = 0.0;
return std::vector<Chromosome*>{}; // silence a warning
}
Main.cpp ++++++++++++++++++++++++++++++++++++++++++++++++
#include "Chromosome.h"
#include "CrossoverStrategies.h" // A bad idea. Forces recompilation when strategies are added
int main()
{
Chromosome * p1 = ChromosomeFactory(/* some construction parameters here */);
p1->m_genes.push_back(0.0); // will fail to compile (incomplete type)
Chromosome * p2 = ChromosomeFactory(/* some construction parameters here */);
// probably should hide the next line with a factory as well
CrossoverStrategy * strategy = new CrossoverStrategyExample1();
strategy->crossover(p1, p2);
}
A quick afterword on security. It always comes at a cost. Generally it makes things harder to use. It makes them harder for an attacker, but it also makes things harder for the legitimate users. Whether it's worth it or not is up to you.
The first, obvious, option is to consider whether the members of Chromosome should or should not be public. Given that you want an arbitrary number of classes to have access to its data, an obvious option is to make that data public.
A second option is for Chromosome to provide a public getter and setter for the affected data, such as;
class Chromosome
{
public:
std::vector<double> getGenes() const {return m_genes;};
bool setGenes(const std::vector<double> &newgenes)
{
bool is_error = true;
if (IsValid(newgnes))
{
is_error = false;
m_genes = newgenes;
}
return is_error; // return true if change is rejected
};
private:
std::vector<double> m_genes;
};
Then all CrossOverStrategy and its derived classes need to do, given valid pointers to Chromosomes, is request the genes, do whatever is needed, and (when done) provide a new set of genes back to selected Chromosomes.
Encapsulation of Chromosome is preserved by various measures, since the only way to change genes is via a member function of Chromosome i.e. there is no way of changing genes in a chromosome outside control of the Chromosome class. Which allows Chromosome to do any checks it likes, and reject bad genes if desired.
There is no need for any other class or function to be a friend of Chromosome. A key advantage is that it is not necessary to change the Chromosome class whenever a new class is derived from CrossOverStrategy.
The trade-off is that genes are retrieved and changes by copying the complete set (potential performance hit of copying). But it avoids the need to break encapsulation of the Chromosome class by providing, directly or indirectly, a reference to its private members to any other classes.
If copying the complete set of chromosomes is a bad thing, work out some additional member functions of Chromosome that allow the caller to request partial changes (e.g. update particular genes, insert a set of genes into a specified place in the vector of genes, etc). These additional functions need to work on the same principle: all changes of genes within a Chromosome go via member functions of Chromosome, and there is no "back door" mechanism for other code to sneak changes through.
If you really want, you can make the setter and getter private members of Chromosome, and make only the base class CrossOverStrategy a friend. Then all CrossOverStrategy needs to do is provide protected helpers that only call the private helpers of Chromosome.
class CrossoverStrategy
{
public:
virtual std::vector<Chromosome*> crossover(Chromosome *parent1, Chromosome *parent2) = 0;
protected:
std::vector<double> getGenes(Chromosome *instance)
{
return instance ? instance->getGenes() : std::vector<double>();
};
bool setGenes(Chromosome *instance, const std::vector<double> &newgenes)
{
return instance ? instance->setGenes(newgenes)) : true; // true indicates error
};
};
That way, only the classes derived from CrossOverStrategy can access the protected helpers. If the workings of Chromosome change, then the only class that needs to be adapted in this case is the base CrossOverStrategy class - since its derived classes don't (directly) access Chromosome at all.
Your idea is fundamentally flawed.
On one hand, you say you don't want just anyone to be able to mess with the vector of genes.
On the other hand, you want any descendant of CrossoverStrategy to be able to mess with the vector of genes.
But there's a contradiction. "Any descendant" of a class is "just anyone". Any user is able to inherit from any class and do what they want with your vector of genes. They only need to go through a small one-time inconvenience of inheriting from CrossoverStrategy.
This is the reason why friendship in C++ is not inherited. If it were, access control would be useless in presence of friend classes.
Of course you can simulate inheritable friendship by having a protected getter in CrossoverStrategy as one of the answers suggests. But doing that defeats the purpose of access control. It makes the arrays of genes as good as public.
I am studying this code:
#include <iostream>
class A
{
public:
A() {};
void fox(A& otherA) { otherA.hello(); }
protected:
void hello() {std::cout << "hello" << std::endl;}
};
A a1,a2;
int main(void)
{
a1.fox(a2);
a1.hello();
}
and am a bit confused as to how saying a1.fox(a2) will compile while saying a1.hello() will not. I would have assumed it would break because while I can call protected and private functions from within a class...allowing me to do that on the otherA object means I would have to be aware that I am calling it from within a member of it's own class. Why/how does this work?
Protected is not instance-by-instance access control, it's a class-by-class access control.
main() (which is not in any class) cannot call private or protected methods of any class at all; hence it fails to call a1.hello().
The implementation of A::fox(A&), on the other hand, is inside the class A, so it can call its private and protected methods, both on itself and on other instances of the class.
Because A is making the call to otherA.hello();. You cannot call into it private or protected code directly, but descendants of A, including A itself, can call into A (descendants cannot access A's private data/methods, but A can access A's private data/methods). Relatedly, A can also access the private data/methods of other instances of A (this is generally how copy constructors and assignment operators work).
In fact, it's the ability to use protected code within the class that enables the creation of some very powerful OO concepts. With that said, I see it as an abuse to call an inner-object's private or protected methods even when possible, but using them directly against yourself is hopefully by design rather than convenience.
In C++, you can provide abstract implementations of classes (or structs for that matter) by marking items as virtual and not providing an implementation.
class A
{
public:
void set_value(const std::string &value)
{
if (is_valid(value))
{
this->value = value;
}
}
const std::string &get_value() const
{
return value;
}
protected:
virtual boolean is_valid(const std::string &value) const = 0;
private:
std::string value;
}
Then
class B : public A
{
protected:
virtual boolean is_valid(const std::string &value) const
{
return value != "abc";
}
}
Notice that A is setup to inherit functionality, and it is built to anticipate it being supplied (granted the example above doesn't really provide a lot of utility, but it does show what I mean).
The access control in C++ is at class level. Not instance level.
Compiler can't possibly know if otherA is actually the same instance or not. You need runtime support to actually determine the identity of the instance to provide such access control.
Apart from the performance problem that this presents, the objective of C++ is to catch errors at compile time, not execution time. As stroustrup says, data-encapsulation and type-safety features can't prevent someone from doing fraud (when the program has unmediated access to all allocated memory).
Now, why is it ok to settle for a solution without runtime check. An anology could help - because as an implementor of a class, you won't rob your own house.
I have a class Widget with some private internals, but I would like to expose these internals to predicate functors (only) via friendship.
class Widget
{
ComponentA a;
ComponentB b;
friend class WidgetPredicate;
};
class WidgetPredicate : public std::unary_function<bool, const Widget&>
{
bool operator () (const Widget& w) const
{
// inspect a and b and make a yes/no decision
}
};
The intent is that I can use the WidgetPredicate function as a sifter in all the std::xxxx_if family of algorithms.
However, I would like to leave some extensibility in the system where a future developer could make new predicates that somehow inheirit the friend status neatly. Is there a good design idiom for this? My current (non) solution is that everything in Widget is public.
I tried toying around with a base class that exposed the internals of Widget to subtypes of WidgetPredicate through protected functions, something like:
class WidgetPredicate : public std::unary ...
{
protected:
const ComponentA& expose_a ( const Widget& w ) const { return w.a; }
const ComponentB& expose_b ( const Widget& w ) const { return w.b; }
public:
virtual bool operator () ...
};
class DerivedWidgetPredicate : public WidgetPredicate
{
public:
virtual bool operator () (const Widget& w)
{
const ComponentA& a = this->expose_a(w); // a can now be inspected/predicated upon
const ComponentB& b = this->expose_b(w); // b ...
}
};
I can live with the potential that now any class could examine Widget's internals just by saying :public WidgetPredicate. I am not trying to protect against malicious developers, so if they say they're a friendly WidgetPredicate then I am willing to take that at face value.
The syntax is also subpar, but I can live with that too. What I don't like the maintainence issue, that when I change the internals of Widget I have to also add new expose() methods to the base predicate. (IMO That process could and should be mechanical).
I could always put the expose methods directly in the Widget class, but IMO at that point I might as well make the fields public and just live with it (ie my current soln).
While it is more expensive, you should define what operations can be allowed for external code and implement them. If you do not want to offer those operations in your public/protected interface, the solution you have posted (declaring another class as a friend and using it as a proxy into your internal code) is a fine solution.
This is subjective, and probably an unwanted comment, but anyway... There is no such thing as a good design mechanism for exposing class internals.
< irony>Just make everything public < /irony>
What you are doing is developing a complex mechanism to break your encapsulation. After you are done with it, all code can access your private members. You state that only predicate functors will have access to the members, but you cannot block non-predicate classes from deriving from the predicate type just to acquire access to the data.
One of the points of encapsulation is reducing dependencies: external code only depend on the public interface, you can always change your internal types and representation and external code will not break (external as not class or friend code). Now, after you have exposed (directly or indirectly) your internals, then those are now part of your public interface and must thus be frozen.
Another point of encapsulation is that you can guarantee invariants on the internal data. After external code have access to the internals, there is no way you can control any kind of invariant on your methods (say keeping the max_size field of a container to the size of the acquired memory) and your class can break due to others misuse.
There are reasons for friendship not being transitive nor inherited: when you declare a class to be a friend of your class, you can check the behavior of that class (and in most cases you are in full control of the friend class). You know that the code you are giving access to does not break your own code.
class Widget
{
friend class BackDoor; // assume that you have implemented it
};
class MaliciousClass1 // third class, malicious or not cannot break into Widget
{
};
class MaliciousClass2 : public BackDoor // You cannot block external code from deriving from BackDoor
{
// Can break into your widget, access and modify anything
};
The door is open for any and everyone to play with your private parts.
Since class friendship is not inherited in C++, what's the best way to "fake" it?
I was thinking about exposing the friend class's private interface through protected methods in the to-be-inherited base-class, but that results in having to write (and maintain) the same interface twice.
Are there any other ways?
The use of a key is a possible solution.
The idea is that you can unlock the operations only if you have a key... but an example is worth thousands on word so let's dive:
// Step 1: The key
class NeedAccess;
namespace details { class Key { friend NeedAccess; Key() {} }; }
// Step 2: NeedAccess
class NeedAccess
{
protected:
static details::Key GetKey() { return details::Key(); }
};
// Step 3: The big one
class BigOne
{
public:
void lockedMethod(details::Key);
};
The matter of key being copy constructable is up to discussion. I don't see what you can gain by preventing it.
Another benefit is that you can have several keys, depending on which method you want to access, this way you grant 'partial' friendship, and your 'partial' friends can't mess around with your private parts, despite the famous claim!
EDIT:
This method is called Limited Friendship, and was discussed on comp.lang.c++.moderated.
The main advantage of this method in comparison to Private Interface, is the loose coupling, since only forward declarations are necessary.
The children of the class with frinedship need to ask there parent to do the access for them.
class CrustyNeighbour
{
private:
friend class Bob;
void useWiFi(std::string const& data);
};
class Bob
{
protected:
useWifi(CrustyNeighbour& neighbour,std::string const& data)
{ neighbour.useWiFi(data);}
};
class Mary: public Bob // Bob's offspring
{
void playHalo(WifiOwner& owner) // WifiOwner derived from CrustyNeighbour
{
useWifi(owner,gameData); // use wifi via his/her parent who access to eighbours wifi
}
};
Not sure if this isn't what you're already thinking about but here's a Virtual Friend example
Unlike protected inheritance, C++ private inheritance found its way into mainstream C++ development. However, I still haven't found a good use for it.
When do you guys use it?
I use it all the time. A few examples off the top of my head:
When I want to expose some but not all of a base class's interface. Public inheritance would be a lie, as Liskov substitutability is broken, whereas composition would mean writing a bunch of forwarding functions.
When I want to derive from a concrete class without a virtual destructor. Public inheritance would invite clients to delete through a pointer-to-base, invoking undefined behaviour.
A typical example is deriving privately from an STL container:
class MyVector : private vector<int>
{
public:
// Using declarations expose the few functions my clients need
// without a load of forwarding functions.
using vector<int>::push_back;
// etc...
};
When implementing the Adapter Pattern, inheriting privately from the Adapted class saves having to forward to an enclosed instance.
To implement a private interface. This comes up often with the Observer Pattern. Typically my Observer class, MyClass say, subscribes itself with some Subject. Then, only MyClass needs to do the MyClass -> Observer conversion. The rest of the system doesn't need to know about it, so private inheritance is indicated.
Note after answer acceptance: This is NOT a complete answer. Read other answers like here (conceptually) and here (both theoretic and practic) if you are interested in the question. This is just a fancy trick that can be achieved with private inheritance. While it is fancy it is not the answer to the question.
Besides the basic usage of just private inheritance shown in the C++ FAQ (linked in other's comments) you can use a combination of private and virtual inheritance to seal a class (in .NET terminology) or to make a class final (in Java terminology). This is not a common use, but anyway I found it interesting:
class ClassSealer {
private:
friend class Sealed;
ClassSealer() {}
};
class Sealed : private virtual ClassSealer
{
// ...
};
class FailsToDerive : public Sealed
{
// Cannot be instantiated
};
Sealed can be instantiated. It derives from ClassSealer and can call the private constructor directly as it is a friend.
FailsToDerive won't compile as it must call the ClassSealer constructor directly (virtual inheritance requirement), but it cannot as it is private in the Sealed class and in this case FailsToDerive is not a friend of ClassSealer.
EDIT
It was mentioned in the comments that this could not be made generic at the time using CRTP. The C++11 standard removes that limitation by providing a different syntax to befriend template arguments:
template <typename T>
class Seal {
friend T; // not: friend class T!!!
Seal() {}
};
class Sealed : private virtual Seal<Sealed> // ...
Of course this is all moot, since C++11 provides a final contextual keyword for exactly this purpose:
class Sealed final // ...
The canonical usage of private inheritance is the "implemented in terms of" relationship (thanks to Scott Meyers' 'Effective C++' for this wording). In other words, the external interface of the inheriting class has no (visible) relationship to the inherited class, but it uses it internally to implement its functionality.
One useful use of private inheritence is when you have a class that implements an interface, that is then registered with some other object. You make that interface private so that the class itself has to register and only the specific object that its registered with can use those functions.
For example:
class FooInterface
{
public:
virtual void DoSomething() = 0;
};
class FooUser
{
public:
bool RegisterFooInterface(FooInterface* aInterface);
};
class FooImplementer : private FooInterface
{
public:
explicit FooImplementer(FooUser& aUser)
{
aUser.RegisterFooInterface(this);
}
private:
virtual void DoSomething() { ... }
};
Therefore the FooUser class can call the private methods of FooImplementer through the FooInterface interface, while other external classes cannot. This is a great pattern for handling specific callbacks that are defined as interfaces.
I think the critical section from the C++ FAQ Lite is:
A legitimate, long-term use for private inheritance is when you want to build a class Fred that uses code in a class Wilma, and the code from class Wilma needs to invoke member functions from your new class, Fred. In this case, Fred calls non-virtuals in Wilma, and Wilma calls (usually pure virtuals) in itself, which are overridden by Fred. This would be much harder to do with composition.
If in doubt, you should prefer composition over private inheritance.
I find it useful for interfaces (viz. abstract classes) that I'm inheriting where I don't want other code to touch the interface (only the inheriting class).
[edited in an example]
Take the example linked to above. Saying that
[...] class Wilma needs to invoke member functions from your new class, Fred.
is to say that Wilma is requiring Fred to be able to invoke certain member functions, or, rather it is saying that Wilma is an interface. Hence, as mentioned in the example
private inheritance isn't evil; it's just more expensive to maintain, since it increases the probability that someone will change something that will break your code.
comments on the desired effect of programmers needing to meet our interface requirements, or breaking the code. And, since fredCallsWilma() is protected only friends and derived classes can touch it i.e. an inherited interface (abstract class) that only the inheriting class can touch (and friends).
[edited in another example]
This page briefly discusses private interfaces (from yet another angle).
Sometimes I find it useful to use private inheritance when I want to expose a smaller interface (e.g. a collection) in the interface of another, where the collection implementation requires access to the state of the exposing class, in a similar manner to inner classes in Java.
class BigClass;
struct SomeCollection
{
iterator begin();
iterator end();
};
class BigClass : private SomeCollection
{
friend struct SomeCollection;
SomeCollection &GetThings() { return *this; }
};
Then if SomeCollection needs to access BigClass, it can static_cast<BigClass *>(this). No need to have an extra data member taking up space.
Private Inheritance to be used when relation is not "is a", But New class can be "implemented in term of existing class" or new class "work like" existing class.
example from "C++ coding standards by Andrei Alexandrescu, Herb Sutter" :-
Consider that two classes Square and Rectangle each have virtual functions for setting their height and width. Then Square cannot correctly inherit from Rectangle, because code that uses a modifiable Rectangle will assume that SetWidth does not change the height (whether Rectangle explicitly documents that contract or not), whereas Square::SetWidth cannot preserve that contract and its own squareness invariant at the same time. But Rectangle cannot correctly inherit from Square either, if clients of Square assume for example that a Square's area is its width squared, or if they rely on some other property that doesn't hold for Rectangles.
A square "is-a" rectangle (mathematically) but a Square is not a Rectangle (behaviorally). Consequently, instead of "is-a," we prefer to say "works-like-a" (or, if you prefer, "usable-as-a") to make the description less prone to misunderstanding.
I found a nice application for private inheritance, although it has a limited usage.
Problem to solve
Suppose you are given the following C API:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
/* raw owning pointer, it's C after all */
char const * name;
/* more variables that need resources
* ...
*/
} Widget;
Widget const * loadWidget();
void freeWidget(Widget const * widget);
#ifdef __cplusplus
} // end of extern "C"
#endif
Now your job is to implement this API using C++.
C-ish approach
Of course we could choose a C-ish implementation style like so:
Widget const * loadWidget()
{
auto result = std::make_unique<Widget>();
result->name = strdup("The Widget name");
// More similar assignments here
return result.release();
}
void freeWidget(Widget const * const widget)
{
free(result->name);
// More similar manual freeing of resources
delete widget;
}
But there are several disadvantages:
Manual resource (e.g. memory) management
It is easy to set up the struct wrong
It is easy to forget freeing the resources when freeing the struct
It is C-ish
C++ Approach
We are allowed to use C++, so why not use its full powers?
Introducing automated resource management
The above problems are basically all tied to the manual resource management. The solution that comes to mind is to inherit from Widget and add a resource managing instance to the derived class WidgetImpl for each variable:
class WidgetImpl : public Widget
{
public:
// Added bonus, Widget's members get default initialized
WidgetImpl()
: Widget()
{}
void setName(std::string newName)
{
m_nameResource = std::move(newName);
name = m_nameResource.c_str();
}
// More similar setters to follow
private:
std::string m_nameResource;
};
This simplifies the implementation to the following:
Widget const * loadWidget()
{
auto result = std::make_unique<WidgetImpl>();
result->setName("The Widget name");
// More similar setters here
return result.release();
}
void freeWidget(Widget const * const widget)
{
// No virtual destructor in the base class, thus static_cast must be used
delete static_cast<WidgetImpl const *>(widget);
}
Like this we remedied all the above problems. But a client can still forget about the setters of WidgetImpl and assign to the Widget members directly.
Private inheritance enters the stage
To encapsulate the Widget members we use private inheritance. Sadly we now need two extra functions to cast between both classes:
class WidgetImpl : private Widget
{
public:
WidgetImpl()
: Widget()
{}
void setName(std::string newName)
{
m_nameResource = std::move(newName);
name = m_nameResource.c_str();
}
// More similar setters to follow
Widget const * toWidget() const
{
return static_cast<Widget const *>(this);
}
static void deleteWidget(Widget const * const widget)
{
delete static_cast<WidgetImpl const *>(widget);
}
private:
std::string m_nameResource;
};
This makes the following adaptions necessary:
Widget const * loadWidget()
{
auto widgetImpl = std::make_unique<WidgetImpl>();
widgetImpl->setName("The Widget name");
// More similar setters here
auto const result = widgetImpl->toWidget();
widgetImpl.release();
return result;
}
void freeWidget(Widget const * const widget)
{
WidgetImpl::deleteWidget(widget);
}
This solution solves all the problems. No manual memory management and Widget is nicely encapsulated so that WidgetImpl does not have any public data members anymore. It makes the implementation easy to use correctly and hard (impossible?) to use wrong.
The code snippets form a compiling example on Coliru.
If you need a std::ostream with some small changes (like in this question) you may need to
Create a class MyStreambuf which derives from std::streambuf and implement changes there
Create a class MyOStream which derives from std::ostream that also initializes and manages an instance of MyStreambuf and passes the pointer to that instance to the constructor of std::ostream
The first idea might be to add the MyStream instance as a data member to the MyOStream class:
class MyOStream : public std::ostream
{
public:
MyOStream()
: std::basic_ostream{ &m_buf }
, m_buf{}
{}
private:
MyStreambuf m_buf;
};
But base classes are constructed before any data members so you are passing a pointer to a not yet constructed std::streambuf instance to std::ostream which is undefined behavior.
The solution is proposed in Ben's answer to the aforementioned question, simply inherit from the stream buffer first, then from the stream and then initialize the stream with this:
class MyOStream : public MyStreamBuf, public std::ostream
{
public:
MyOStream()
: MyStreamBuf{}
, basic_ostream{ this }
{}
};
However the resulting class could also be used as a std::streambuf instance which is usually undesired. Switching to private inheritance solves this problem:
class MyOStream : private MyStreamBuf, public std::ostream
{
public:
MyOStream()
: MyStreamBuf{}
, basic_ostream{ this }
{}
};
If derived class
- needs to reuse code and
- you can't change base class and
- is protecting its methods using base's members under a lock.
then you should use private inheritance, otherwise you have danger of unlocked base methods exported via this derived class.
Sometimes it could be an alternative to aggregation, for example if you want aggregation but with changed behaviour of aggregable entity (overriding the virtual functions).
But you're right, it has not many examples from the real world.
A class holds an invariant. The invariant is established by the constructor. However, in many situations it's useful to have a view of the representation state of the object (which you can transmit over network or save to a file - DTO if you prefer). REST is best done in terms of an AggregateType. This is especially true if you're const correct. Consider:
struct QuadraticEquationState {
const double a;
const double b;
const double c;
// named ctors so aggregate construction is available,
// which is the default usage pattern
// add your favourite ctors - throwing, try, cps
static QuadraticEquationState read(std::istream& is);
static std::optional<QuadraticEquationState> try_read(std::istream& is);
template<typename Then, typename Else>
static std::common_type<
decltype(std::declval<Then>()(std::declval<QuadraticEquationState>()),
decltype(std::declval<Else>()())>::type // this is just then(qes) or els(qes)
if_read(std::istream& is, Then then, Else els);
};
// this works with QuadraticEquation as well by default
std::ostream& operator<<(std::ostream& os, const QuadraticEquationState& qes);
// no operator>> as we're const correct.
// we _might_ (not necessarily want) operator>> for optional<qes>
std::istream& operator>>(std::istream& is, std::optional<QuadraticEquationState>);
struct QuadraticEquationCache {
mutable std::optional<double> determinant_cache;
mutable std::optional<double> x1_cache;
mutable std::optional<double> x2_cache;
mutable std::optional<double> sum_of_x12_cache;
};
class QuadraticEquation : public QuadraticEquationState, // private if base is non-const
private QuadraticEquationCache {
public:
QuadraticEquation(QuadraticEquationState); // in general, might throw
QuadraticEquation(const double a, const double b, const double c);
QuadraticEquation(const std::string& str);
QuadraticEquation(const ExpressionTree& str); // might throw
}
At this point, you might just store collections of cache in containers and look it up on construction. Handy if there's some real processing. Note that cache is part of the QE: operations defined on the QE might mean the cache is partially reusable (e.g., c does not affect the sum); yet, when there's no cache, it's worth to look it up.
Private inheritance can almost always modelled by a member (storing reference to the base if needed). It's just not always worth it to model that way; sometimes inheritance is the most efficient representation.
Just because C++ has a feature, doesn't mean it's useful or that it should be used.
I'd say you shouldn't use it at all.
If you're using it anyway, well, you're basically violating encapsulation, and lowering cohesion. You're putting data in one class, and adding methods that manipulates the data in another one.
Like other C++ features, it can be used to achieve side effects such as sealing a class (as mentioned in dribeas' answer), but this doesn't make it a good feature.