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.
Related
Why does this compile:
class FooBase
{
protected:
void fooBase(void);
};
class Foo : public FooBase
{
public:
void foo(Foo& fooBar)
{
fooBar.fooBase();
}
};
but this does not?
class FooBase
{
protected:
void fooBase(void);
};
class Foo : public FooBase
{
public:
void foo(FooBase& fooBar)
{
fooBar.fooBase();
}
};
On the one hand C++ grants access to private/protected members for all instances of that class, but on the other hand it does not grant access to protected members of a base class for all instances of a subclass.
This looks rather inconsistent to me.
I have tested compiling with VC++ and with ideone.com and both compile the first but not the second code snippet.
When foo receives a FooBase reference, the compiler doesn't know whether the argument is a descendant of Foo, so it has to assume it's not. Foo has access to inherited protected members of other Foo objects, not all other sibling classes.
Consider this code:
class FooSibling: public FooBase { };
FooSibling sib;
Foo f;
f.foo(sib); // calls sib.fooBase()!?
If Foo::foo can call protected members of arbitrary FooBase descendants, then it can call the protected method of FooSibling, which has no direct relationship to Foo. That's not how protected access is supposed to work.
If Foo needs access to protected members of all FooBase objects, not just those that are also known to be Foo descendants, then Foo needs to be a friend of FooBase:
class FooBase
{
protected:
void fooBase(void);
friend class Foo;
};
The C++ FAQ summarizes this issue nicely:
[You] are allowed to pick your own pockets, but you are not allowed to pick your father's pockets nor your brother's pockets.
The key point is that protected grants you access to your own copy of the member, not to those members in any other object. This is a common misconception, as more often than not we generalize and state protected grants access to the member to the derived type (without explicitly stating that only to their own bases...)
Now, that is for a reason, and in general you should not access the member in a different branch of the hierarchy, as you might break the invariants on which other objects depend. Consider a type that performs an expensive calculation on some large data member (protected) and two derived types that caches the result following different strategies:
class base {
protected:
LargeData data;
// ...
public:
virtual int result() const; // expensive calculation
virtual void modify(); // modifies data
};
class cache_on_read : base {
private:
mutable bool cached;
mutable int cache_value;
// ...
virtual int result() const {
if (cached) return cache_value;
cache_value = base::result();
cached = true;
}
virtual void modify() {
cached = false;
base::modify();
}
};
class cache_on_write : base {
int result_value;
virtual int result() const {
return result_value;
}
virtual void modify() {
base::modify();
result_value = base::result();
}
};
The cache_on_read type captures modifications to the data and marks the result as invalid, so that the next read of the value recalculates. This is a good approach if the number of writes is relatively high, as we only perform the calculation on demand (i.e. multiple modifies will not trigger recalculations). The cache_on_write precalculates the result upfront, which might be a good strategy if the number of writes is small, and you want deterministic costs for the read (think low latency on reads).
Now, back to the original problem. Both cache strategies maintain a stricter set of invariants than the base. In the first case, the extra invariant is that cached is true only if data has not been modified after the last read. In the second case, the extra invariant is that result_value is the value of the operation at all times.
If a third derived type took a reference to a base and accessed data to write (if protected allowed it to), then it would break with the invariants of the derived types.
That being said, the specification of the language is broken (personal opinion) as it leaves a backdoor to achieve that particular result. In particular, if you create a pointer to member of a member from a base in a derived type, access is checked in derived, but the returned pointer is a pointer to member of base, which can be applied to any base object:
class base {
protected:
int x;
};
struct derived : base {
static void modify( base& b ) {
// b.x = 5; // error!
b.*(&derived::x) = 5; // allowed ?!?!?!
}
}
In both examples Foo inherits a protected method fooBase. However, in your first example you try to access the given protected method from the same class (Foo::foo calls Foo::fooBase), while in the second example you try to access a protected method from another class which isn't declared as friend class (Foo::foo tries to call FooBase::fooBase, which fails, the later is protected).
In the first example you pass an object of type Foo, which obviously inherits the method fooBase() and so is able to call it. In the second example you are trying to call a protected function, simply so, regardless in which context you can't call a protected function from a class instance where its declared so.
In the first example you inherit the protected method fooBase, and so you have the right to call it WITHIN Foo context
I tend to see things in terms of concepts and messages. If your FooBase method was actually called "SendMessage" and Foo was "EnglishSpeakingPerson" and FooBase was SpeakingPerson, your protected declaration is intended to restrict SendMessage to between EnglishSpeakingPersons (and subclasses eg: AmericanEnglishSpeakingPerson, AustralianEnglishSpeakingPerson) . Another type FrenchSpeakingPerson derived from SpeakingPerson would not be able to receive a SendMessage, unless you declared the FrenchSpeakingPerson as a friend, where 'friend' meant that the FrenchSpeakingPerson has a special ability to receive SendMessage from EnglishSpeakingPerson (ie can understand English).
In addition to hobo's answer you may seek a workaround.
If you want the subclasses to want to call the fooBase method you can make it static. static protected methods are accessible by subclasses with all arguments.
You can work around without a friend like so...
class FooBase
{
protected:
void fooBase(void);
static void fooBase(FooBase *pFooBase) { pFooBase->fooBase(); }
};
This avoids having to add derived types to the base class. Which seems a bit circular.
What I've seen and been taught about encapsulation is that we can have data members as private and member functions are public.
But C++ Primer defines encapsulation as:
Separation of implementation from interface; encapsulation hides
the implementation details of a type. In C++, encapsulation is enforced by putting the implementation in the private part of a class.
The last line is the confusing part: putting the implementation in the private part of a class. By implementation, he means the function definitions, right? I mean, I've never seen a function declared public (as prototype) and implemented in private.
I'm really confused. Please explain what he's trying to say with a simple example.
The concept being explained is more abstract than you're thinking about it. The "interface" is "what callers expect the object to do". And the implementation is technically how the class actually carries out those operations.
So for example, take a List class. Code that uses a List should only care about its interface: things like addObject(), clear(), getSize(), sort().
But the implementation of List -- which callers should not care about -- may vary drastically on how to accomplish this. For example the data could be stored as a linked list. Or maybe as a dynamic array. This is "private" implementation details that only the List class needs to care about. There will indeed probably be a private: method called reallocate() or so. Callers should never use this; it's an implementation detail -- not part of the public interface. Callers should not care how the List allocates its storage.
Similarly, a sort() method implies it will sort objects in the list. That's the interface. But the implementation may use any number of algorithms to perform the sort. The implementation is a private detail - and may be done in private methods. In any case it's hidden from callers.
template<typename T>
class List
{
public:
// public members are part of the interface: the externally-visible behavior "contract" your object guarantees.
void addObject(const T& obj)
{
// call private methods to help carry out implementation.
ensureCapacity(this->sizeAllocated + 1);
this->sizeAdvertized += 1;
// ... and copy the object into the right position in this->data...
}
size_t getSize() const
{
return this->sizeAdvertized;
}
// ... other members like clear(), sort()...
private:
T* data;
size_t sizeAllocated;
size_t sizeAdvertized;
// this needs to be private because it's not part of the interface. Callers
// should never need to call this.
void ensureCapacity(size_t requestedCapacity)
{
if(sizeAllocated >= requestedCapacity)
return;// already have enough storage available.
// ... reallocate this->data, copy existing items to the new array...
this->sizeAllocated = requestedCapacity;
}
};
And finally to address what you said:
I mean, I've never seen a function declared public (as prototype) and implemented in private.
"Private" again is more abstract than you're thinking. The implementation of a class is basically always "private" in that it's hidden from callers. It doesn't necessarily mean the private: access specifier. It just means that it's not exposed to callers. Implementation of public methods fits this description.
You can indeed have private functions (methods) in a class. Consider:
class X
{
public:
// public interface - this never changes and you provide documentation for it
void do_something();
private:
// this private interface is likely to change. consumers of this class
// are prevented from calling these methods unless they are friends
void first_private_thing();
void second_private_thing();
};
// definition
void X::do_something()
{
// private implementation in public method
first_private_thing();
second_private_thing();
}
there are further extensions on this theme, for example:
class Base
{
public:
// public non-virtual interface
void do_something();
private:
// calls private virtual implementation
virtual void do_something_impl() = 0;
};
// definition:
void Base::do_something()
{
do_something_impl();
}
Why does this compile:
class FooBase
{
protected:
void fooBase(void);
};
class Foo : public FooBase
{
public:
void foo(Foo& fooBar)
{
fooBar.fooBase();
}
};
but this does not?
class FooBase
{
protected:
void fooBase(void);
};
class Foo : public FooBase
{
public:
void foo(FooBase& fooBar)
{
fooBar.fooBase();
}
};
On the one hand C++ grants access to private/protected members for all instances of that class, but on the other hand it does not grant access to protected members of a base class for all instances of a subclass.
This looks rather inconsistent to me.
I have tested compiling with VC++ and with ideone.com and both compile the first but not the second code snippet.
When foo receives a FooBase reference, the compiler doesn't know whether the argument is a descendant of Foo, so it has to assume it's not. Foo has access to inherited protected members of other Foo objects, not all other sibling classes.
Consider this code:
class FooSibling: public FooBase { };
FooSibling sib;
Foo f;
f.foo(sib); // calls sib.fooBase()!?
If Foo::foo can call protected members of arbitrary FooBase descendants, then it can call the protected method of FooSibling, which has no direct relationship to Foo. That's not how protected access is supposed to work.
If Foo needs access to protected members of all FooBase objects, not just those that are also known to be Foo descendants, then Foo needs to be a friend of FooBase:
class FooBase
{
protected:
void fooBase(void);
friend class Foo;
};
The C++ FAQ summarizes this issue nicely:
[You] are allowed to pick your own pockets, but you are not allowed to pick your father's pockets nor your brother's pockets.
The key point is that protected grants you access to your own copy of the member, not to those members in any other object. This is a common misconception, as more often than not we generalize and state protected grants access to the member to the derived type (without explicitly stating that only to their own bases...)
Now, that is for a reason, and in general you should not access the member in a different branch of the hierarchy, as you might break the invariants on which other objects depend. Consider a type that performs an expensive calculation on some large data member (protected) and two derived types that caches the result following different strategies:
class base {
protected:
LargeData data;
// ...
public:
virtual int result() const; // expensive calculation
virtual void modify(); // modifies data
};
class cache_on_read : base {
private:
mutable bool cached;
mutable int cache_value;
// ...
virtual int result() const {
if (cached) return cache_value;
cache_value = base::result();
cached = true;
}
virtual void modify() {
cached = false;
base::modify();
}
};
class cache_on_write : base {
int result_value;
virtual int result() const {
return result_value;
}
virtual void modify() {
base::modify();
result_value = base::result();
}
};
The cache_on_read type captures modifications to the data and marks the result as invalid, so that the next read of the value recalculates. This is a good approach if the number of writes is relatively high, as we only perform the calculation on demand (i.e. multiple modifies will not trigger recalculations). The cache_on_write precalculates the result upfront, which might be a good strategy if the number of writes is small, and you want deterministic costs for the read (think low latency on reads).
Now, back to the original problem. Both cache strategies maintain a stricter set of invariants than the base. In the first case, the extra invariant is that cached is true only if data has not been modified after the last read. In the second case, the extra invariant is that result_value is the value of the operation at all times.
If a third derived type took a reference to a base and accessed data to write (if protected allowed it to), then it would break with the invariants of the derived types.
That being said, the specification of the language is broken (personal opinion) as it leaves a backdoor to achieve that particular result. In particular, if you create a pointer to member of a member from a base in a derived type, access is checked in derived, but the returned pointer is a pointer to member of base, which can be applied to any base object:
class base {
protected:
int x;
};
struct derived : base {
static void modify( base& b ) {
// b.x = 5; // error!
b.*(&derived::x) = 5; // allowed ?!?!?!
}
}
In both examples Foo inherits a protected method fooBase. However, in your first example you try to access the given protected method from the same class (Foo::foo calls Foo::fooBase), while in the second example you try to access a protected method from another class which isn't declared as friend class (Foo::foo tries to call FooBase::fooBase, which fails, the later is protected).
In the first example you pass an object of type Foo, which obviously inherits the method fooBase() and so is able to call it. In the second example you are trying to call a protected function, simply so, regardless in which context you can't call a protected function from a class instance where its declared so.
In the first example you inherit the protected method fooBase, and so you have the right to call it WITHIN Foo context
I tend to see things in terms of concepts and messages. If your FooBase method was actually called "SendMessage" and Foo was "EnglishSpeakingPerson" and FooBase was SpeakingPerson, your protected declaration is intended to restrict SendMessage to between EnglishSpeakingPersons (and subclasses eg: AmericanEnglishSpeakingPerson, AustralianEnglishSpeakingPerson) . Another type FrenchSpeakingPerson derived from SpeakingPerson would not be able to receive a SendMessage, unless you declared the FrenchSpeakingPerson as a friend, where 'friend' meant that the FrenchSpeakingPerson has a special ability to receive SendMessage from EnglishSpeakingPerson (ie can understand English).
In addition to hobo's answer you may seek a workaround.
If you want the subclasses to want to call the fooBase method you can make it static. static protected methods are accessible by subclasses with all arguments.
You can work around without a friend like so...
class FooBase
{
protected:
void fooBase(void);
static void fooBase(FooBase *pFooBase) { pFooBase->fooBase(); }
};
This avoids having to add derived types to the base class. Which seems a bit circular.
Earlier, I asked a question on how to call a static member's member functions so as to initialize it before making actual use of the static object. Then, I realized that I was perhaps making use of the static member in a wrong way, which led to this question:
Given a particular class, MyClass, in how many ways can we design our code so that MyClass can gain access to the member functions of another class, YourClass? [N.B. Assume a generic situation where MyClass is declared in MyClass.h and defined in MyClass.cpp, and similarly for YourClass.]
I can think of a few, but being far from an expert, I guess you could name several others:
Containment: This can come in several 'flavors', with direct containment of a YourClass object being one option, while containing a pointer or reference to the object being another option:
class MyClass
{
public:
// Some MyClass members...
private:
YourClass instance; // or YourClass* instance / YourClass& instance;
// Some other MyClass members...
};
a) Of course, direct containment is convenient, but I can think of one immediate drawback: if YourClass is a bit hefty in terms of memory requirement, and you have several MyClass instances (as in my linked question), containing the object directly will be out of the question. Besides, the has-a relationship does not always make sense.
b) Having a pointer or a reference to the object might make better sense in that case. Using a reference has the problem that you might end up referring to an object which does not exist anymore, so you have to make sure that the YourClass object exists for the duration of the existence of the MyClass object.
c) In the case of a pointer, the problem above still exists, but you can more easily reassign the pointer to a new object.
Inheritance: One can inherit from the YourClass object, so that the members are inherited, such as:
class MyClass : public YourClass
{
public:
// Some MyClass members...
private:
// Some other MyClass members...
};
a) This is also very simple to set up for a few classes, but may become unwieldy for general use. For example, if YourClass was a random number generator, it wouldn't necessarily make sense to say MyClass is-a random number generator. One can of course define a wrapper class for the random number generator, say call it Randomizable and then MyClass could inherit from Randomizable, which makes good sense.
I would personally like to know more about the pros and cons of static members, global objects, singletons, and how they are correctly used. So, from a 'meta' point of view, what other methods or patterns would work?
PS. Though I'm asking from a C++ perspective, I guess the same could be said to apply for many other object oriented languages, so don't worry about giving examples in other languages.
There are basics about C++ class membership access.
You can access a member of your own direct class (public, protected or private)
class Foo {
public:
int fooMember;
};
int main() {
Foo foo;
foo.fooMember = 1;
}
You can access protect and public members of your parent class within the child class, and then depending on the inheritance indicator in the child class declaration the members of the parent are passed on to public, next-child, or kept private
class Animal {
protected:
int feet;
int age;
public:
enum color { blue, red, green, pink } color;
Animal(int feet) { this->feet = feet; }
bool getFeet() { return feet; }
void setAge(int a) { age = a; }
};
class Elephant: public Animal {
public:
Elephant(void):Animal(4) { }
int hasFeet(void) { return (feet > 0); }
};
// Here you can override stuff too so:
class Fish: protected Animal {
public:
int teeth;
enum Type { freshWater, saltWater } type;
Fish(void):Animal(0) { }
};
class Mackerel: private Fish {
public:
Mackerel(): Fish() { teeth = 12; } /* compiles */
};
class SubMackerel: public Mackerel {
public:
SubMackerel() { teeth = 8; } /* does not compile teeth not accessible here */
} ;
int main() {
Elephant pink;
Fish fishy;
Mackerel mack;
pink.color = Animal::blue;
// this won't compile since color is protected in Fish
// fishy.color = green;
fishy.type = freshWater;
// mack.type = saltWater; // will fail
}
the last way is to declare friends. A friend class can access all public and private members of the class it is a friend to.
Well this should be a start... You can read more about it
I have been looking for the answer about the kind of same thing , and landed here.
Buy anyway , atleast I should tell you what till now I have learned about this problem.
Avoid using another class as data member , if that's not the case and you have to use it, then use pointer to that another class.
Now, if you are using pointer to the another class , always deep copy , so you have to provide a copy constructor with a deep copy to avoid invalid address assignment .
Or just use smart pointers .
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.