Pimpl idiom with inheritance - c++

I want to use pimpl idiom with inheritance.
Here is the base public class and its implementation class:
class A
{
public:
A(){pAImpl = new AImpl;};
void foo(){pAImpl->foo();};
private:
AImpl* pAImpl;
};
class AImpl
{
public:
void foo(){/*do something*/};
};
And I want to be able to create the derived public class with its implementation class:
class B : public A
{
public:
void bar(){pAImpl->bar();}; // Can't do! pAimpl is A's private.
};
class BImpl : public AImpl
{
public:
void bar(){/*do something else*/};
};
But I can't use pAimpl in B because it is A's private.
So I see some ways to solve it:
Create BImpl* pBImpl member in B, and pass it to A with additional A constructor, A(AImpl*).
Change pAImpl to be protected (or add a Get function), and use it in B.
B shouldn't inherit from A. Create BImpl* pBImpl member in B, and create foo() and bar() in B, that will use pBImpl.
Any other way?
What should I choose?

class A
{
public:
A(bool DoNew = true){
if(DoNew)
pAImpl = new AImpl;
};
void foo(){pAImpl->foo();};
protected:
void SetpAImpl(AImpl* pImpl) {pAImpl = pImpl;};
private:
AImpl* pAImpl;
};
class AImpl
{
public:
void foo(){/*do something*/};
};
class B : public A
{
public:
B() : A(false){
pBImpl = new BImpl;
SetpAImpl(pBImpl);
};
void bar(){pBImpl->bar();};
private:
BImpl* pBImpl;
};
class BImpl : public AImpl
{
public:
void bar(){/*do something else*/};
};

I think the best way from a purely object-oriented-theoretical perspective is to not make BImpl inherit from AImpl (is that what you meant in option 3?). However, having BImpl derive from AImpl (and passing the desired impl to a constructor of A) is OK as well, provided that the pimpl member variable is const. It doesn't really matter whether you use a get functions or directly access the variable from derived classes, unless you want to enforce const-correctness on the derived classes. Letting derived classes change pimpl isn't a good idea - they could wreck all of A's initialisation - and nor is letting the base class change it a good idea. Consider this extension to your example:
class A
{
protected:
struct AImpl {void foo(); /*...*/};
A(AImpl * impl): pimpl(impl) {}
AImpl * GetImpl() { return pimpl; }
const AImpl * GetImpl() const { return pimpl; }
private:
AImpl * pimpl;
public:
void foo() {pImpl->foo();}
friend void swap(A&, A&);
};
void swap(A & a1, A & a2)
{
using std::swap;
swap(a1.pimpl, a2.pimpl);
}
class B: public A
{
protected:
struct BImpl: public AImpl {void bar();};
public:
void bar(){static_cast<BImpl *>(GetImpl())->bar();}
B(): A(new BImpl()) {}
};
class C: public A
{
protected:
struct CImpl: public AImpl {void baz();};
public:
void baz(){static_cast<CImpl *>(GetImpl())->baz();}
C(): A(new CImpl()) {}
};
int main()
{
B b;
C c;
swap(b, c); //calls swap(A&, A&)
//This is now a bad situation - B.pimpl is a CImpl *, and C.pimpl is a BImpl *!
//Consider:
b.bar();
//If BImpl and CImpl weren't derived from AImpl, then this wouldn't happen.
//You could have b's BImpl being out of sync with its AImpl, though.
}
Although you might not have a swap() function, you can easily conceive of similar problems occurring, particularly if A is assignable, whether by accident or intention. It's a somewhat subtle violation of the Liskov substitutability principle. The solutions are to either:
Don't change the pimpl members after construction. Declare them to be AImpl * const pimpl. Then, the derived constructors can pass an appropriate type and the rest of the derived class can downcast confidently. However, then you can't e.g. do non-throwing swaps, assignments, or copy-on-write, because these techniques require that you can change the pimpl member. However however, you're probably not really intending to do these things if you have an inheritance hierarchy.
Have unrelated (and dumb) AImpl and BImpl classes for A and B's private variables, respectively. If B wants to do something to A, then use A's public or protected interface. This also preserves the most common reason to using pimpl: being able to hide the definition of AImpl away in a cpp file that derived classes can't use, so half your program doesn't need to recompile when A's implementation changes.

As stefan.ciobaca said, if you really wanted A to be extendable, you'd want pAImpl to be protected.
However, your definition in B of void bar(){pAImpl->bar();}; seems odd, as bar is a method on BImpl and not AImpl.
There are at least three easy alternatives that would avoid that issue:
Your alternative (3).
A variation on (3) in which BImpl extends AImpl (inheriting the existing implementation of foo rather than defining another), BImpl defines bar, and B uses its private BImpl* pBImpl to access both.
Delegation, in which B holds private pointers to each of AImpl and BImpl and forwards each of foo and bar to the appropriate implementer.

I would do (1) because A's privates are or no business for B.
Actually I would not pass it to A as you suggest, because A makes its own in A::A().
Calling pApimpl->whatever() from Bis also not appropriate (private means private).

The correct way is to do (2).
In general, you should probably consider to make all you member variables protected by default instead of private.
The reason most programmers choose private is that they don't think about others who want to derive from their class and most introductory C++ manuals teach this style, in the sense that all the examples use private.
EDIT
Code duplication and memory allocation are undesired side-effects of using the pimp design pattern and cannot be avoided to my knowledge.
If you need to have Bimpl inherit Aimpl and you want to expose a consistent interface to them through A and B, B would also need to inherit A.
One thing you can do to simplify things in this scenario is to have B inherit from A and only change the contructor such that B::B(...) {} creates a Bimpl, and add dispatches for all methods of Bimpl that are not in Aimpl.

Related

Virtual but not multiple inheritance to call grandparent constructor

I'm having this kind of code:
class Ref {<undefined>};
Ref refObjectForA, refObjectForB;
class Base
{
public:
Base(const Ref & iRef) : _ref(iRef) {}
virtual ~Base() {}
const Ref & ref;
};
class A: public Base
{
public:
A() : Base(refObjectForA) {}
virtual ~A() {}
};
class B: public A
{
public:
B() : Base(refObjectForB) {} // won't compile: Base is not direct base of B
virtual ~B() {}
};
As the attribute is a reference, I think I can only set it in constructor, so I need to call Base constructor in B().
I've found two ways: providing a "forward" constructor in A (but this implies adding code in all classes that might be inherited):
A(const Ref& iRef): Base(iRef)
or using virtual inheritance:
class A: public virtual Base
Second option allows more straightforward code in B implementation but I'm wondering if I'm misusing virtual inheritance in an ugly trick or if it is a valid usecase.
Can I use virtual inheritance in this case?
If no, for what reason?
One of the "unexpected" behaviors I've found is that it's not possible to static_cast a Base pointer to a B pointer because of the virtual inheritance.
Moreover I'm also wondering why it works (I mean why a B().ref == refObjectForB): I would think that the implicit call to default A() constructor in B() would overwrite the ref attribute after explicit Base constructor, but maybe it's not true with virtual inheritance.
The best option I can see if you want to stick to your inheritance hierarchy is to implement protected constructors taking a reference which they'll forward to the Base class. Making a constructor protected makes sure that a (final) instance can't be constructed using this constructor, so it will only be used in subclasses to initialize the super classes.
With some more or less ugly and dangerous macro, this becomes easy to be written:
#define REF_FORWARD_CTOR(ClassName, DirectSuperClassName) \
protected: ClassName(class Ref &r) : DirectSuperClassName(r) {} \
public:
class A : public Base
{
REF_FORWARD_CTOR(A, Base)
public:
A() : Base(refObjectForA) {} // normal ctor
};
class B : public A
{
REF_FORWARD_CTOR(B, A)
public:
B() : A(refObjectForB) {} // normal ctor
};
An alternative design would be to let A and B both derive (directly) from Base. Then, add functionalities by using multiple inheritance and "common classes", maybe private, depending on what they are for:
class Base {
};
class Common {
// common stuff used by both A and B
};
class A : public Base, public Common {
// no further stuff here
};
class B : public Base, public Common {
// add more stuff, or put it in a common super-class again,
// if some classes want to inherit from B again
};
The problem with this design is that functionality in Common can't access the stuff in A and B. To solve this, do one of the following:
If only static stuff is required: Use CRTP to specify A / B in a concrete Common type: Common<A> can then use A::..., but doesn't have anything to do with a concrete instance of A
If an instance is required: provide a pointer / reference in the constructor of Common (slight overhead)
Putting the first two solutions together: Use CRTP, implement wrapper functions in A and B which call functions in Common<A> and Common<B> providing this (which is a A* or B* via an extra parameter.
Same as above, but the class Common can also be non-templated (no CRTP) if you overload / template these functions on this pointer argument ("CRTP on functions", if you want to call it like that). Code speaks louder than words. (Example code is without your references and focuses on the "common class".)
Yes you can technically use virtual inheritance to achieve the goal of providing the reference in the most derived class.
And yes, that's a design smell.
Your classes should not need to be aware of anything but their immediate bases (virtual inheritance is the exception to the rule, when it's needed for other reasons).
Sticking to the proposed classes hierarchy, in order to solve the problem it is enough to use the "using-declaration" to bring the Base's constructor to the protected part of the class A, i.e.:
class A: public Base
{
public:
A() : Base(refObjectForA) {}
virtual ~A() {}
protected:
using Base::Base;
};

a way in c++ to hide a specific function

i have an inheritance struct A : public B, i want to hide individual functions from B, is this possible?
i know the opposite is possible using using BMethod in the A declaration.
cheers
If you want to selectively hide functions from B it does not make much sense to use public inheritance in the first place.
Use private inheritance & selectively bring methods from B into the scope of A:
struct B{
void method1(){};
void method2(){};
};
struct A : private B{
using B::method1;
};
A a;
a.method1();
a.method2(); //error method2 is not accesible
There is an issue here: this would be a direct violation of the Liskov Substitution Principle, namely A would not act as a B any longer.
If you wish to reuse B implementation, the solution is simply to do so:
class A
{
public:
void foo() { return b.foo(); }
void bar() { return b.bar(); }
// ...
private:
B b;
};
Don't abuse inheritance, use composition instead
The using keyword can be used to change visibility
struct A
{
void method1();
};
struct B: public A
{
void method2();
private:
using A::method1;
};
Aside from the ways described in the previous answers—composition, private inheritance, and non-private inheritance but with the inherited method declared private—another way is to explicitly delete the inherited method:
#include <iostream>
struct A {
void foo() { std::cout << "foo\n"; }
};
struct B : A {
void foo() = delete;
};
int main() {
B b;
b.foo(); // COMPILER ERROR
}
Although the b.foo() call produces a compiler error, client code can still call the base class’s version by qualifying with the base class identifier A:
b.A::foo(); // compiles, outputs 'foo' to console
This explicit deletion way works when foo is not a virtual non-deleted method in A. By C++11 Standard §10.3/16, this explicit deletion is ill-formed when the deleted method in the derived class overrides a virtual non-deleted method of the base class. For more info on this restriction, see the answers to the SO question C++11 Delete Overriden Method.
You can't "hide it" per se, but you can make it a compile time error to call it. Example:
struct A
{
void AMethod() {}
};
class B : public A
{
void AMethod() {} //Hides A::AMethod
};
int main()
{
B myB;
myB.AMethod(); //Error: AMethod is private
static_cast<A*>(&myB)->AMethod(); //Ok
return 0;
}
Examples on codepad with the error, and without.
That all said, despite this being possible, you really shouldn't do it. You'll confuse the hell out of clients.
EDIT: Note that you can also do this with virtual functions (And with the error).
To those that are suggesting composition... this might not be the best possible way of going about things. My understanding is that the Liskov Substitution Principle only states that there's the possibility of the functions from the base class being used on the child, not that they necessarily should be. For example, for a particular base class you may have multiple functions that essentially perform the same operation, but for different specific cases. In the derived class you may want to abstract these public functions away in favor of simplifying the user's interface. This is where private inheritance can be used. Private inheritance might also be a necessity, if we have protected functions in the base class that we don't want the user of the base class to call, yet would be invaluable to the derived class.
In short, if you HAVE to, use private inheritance, but composition is preferred in most cases.
There is yet another approach.
class A{
void f1();
void f2();
void f3();
}
class BInterface{
void f2();
void f3();
}
class B : public A, BInterface
{
}
BInterface b = new B();
b->f1(); //doesn't work since f1 is not declared in BInterface
b->f2(); //should work
b->f3(); //should work
delete(b);
Use BInterface as a filter for inherited classes to exclude undesirable methods. Liskov Substitution principle isn't violated in this case since an object of BInterface class is not an object of A class even though that an object of B class is an object of BInterface class.
If the methods are private in B, then they will remain hidden to a even if you use public inheritance.
Can't alter the visibility of the original method.
You could create a method in struct A with the same name and have that method be private, but that doesn't prevent the method from being called when an instance of struct A is being referenced by a variable of type B.
Why don't you make it Virtual in the base class and override it in its Children? (more help)

Instance of a subclass in a parent class

I have two classes in a class hierarchy where a parent class needs to have an instance of a class derived from it as a member variable. As an example:
class B;
class A {
public:
B* binst;
A();
};
class B : public A {
};
A::A() {
binst = new B;
}
Obviously, this causes an infinite recursion in the constructors, because to create a new B you have to call A's constructor, which creates a new B which calls A's constructor, and so ad infinitum.
Is there a way around this? The problem I'm having in this is that A has to have a B in it, but B must be derived from A, and there's not a way to prevent that.
To get an idea of why I need to do this, consider an object oriented hierarchy for a scripting language (like python or ruby or lua, etc):
All instances of anything are derived from a base class, Object.
Object has a method lookup table, which is an instance of MethodTable.
MethodTable is derived from Object, and must be, for the scripting language to be able to operate on it.
"Object has a method lookup table"
"MethodTable is derived from Object"
Putting aside coding concerns, do these statements really make sense together from even a conceptual standpoint? Should a MethodTable have its own MethodTable which then has its own MethodTable... etc?
I'd say it sounds like you need to refactor your concepts a bit. For instance, perhaps Object itself should somehow be responsible for exposing the necessary pieces of its MethodTable member. Thus not requiring MethodTable itself to be an Object. (There may be various other feasible designs too. It's hard to say without deeper knowledge of the actual project.)
Edit: Typically, compiler/implementation-internal types don't derive from language-dependent types. If you look at the internals of Java, their inheritance implementation won't derive from Object. Object is a language construction, it's part of your language's interface. A method table is part of the implementation. A method table should not be operated on by the language, it should be operated on by the implementation.
Moreover, enforced deriving from Object is a stupid thing to do and it happens because you didn't consider the language design and how the users were going to write generic code properly. This is especially true in dynamically typed languages like Lua or Python.
Object could have a private MethodTableImpl member and a public getter that returns a MethodTable. MethodTable contains a MethodTableImpl and derives from Object.
I don't know the purpose of your classes but here is a suggestion :
class A
{
public:
virtual void func DoIt () = 0;
...
};
class B : public virtual A
{
public:
};
class C : public virtual A ,B
{
void func DoIt () { /* statements */ }
};
now there is only 1 instance of class A.
It would be helpful to understand exactly are you trying to achieve via this construct.
As you've noted yourself, this is effectively like having A's constructor construct an instance of A, and that's an unavoidable path to stack overflow.
A more general solution would be to provide a set_subclass method for a pointer to an instance of A, which could then be populated by any subclass of A, not just B.
class A {
public:
A();
virtual ~A();
set_subclass(A* sub) { subclass = sub; }
private:
A* subclass;
};
// List(1) or Stream(2) using inheritance
struct B;
struct A {
B *inst;
A(B *inst_) : inst(inst_) {}
A() : inst(0) {}
};
struct B : A {
B(B *_inst) : A(inst) {}
// chose option 1 or 2
B() : A() {} // option 1: List
B() : A(0) {} // same as above
B() : A(this) {} // option 2: Stream
};
auto B3 = new B(new B( new B));
// This is either a length 3 list (1)
// or a stream (2) implemented by self ref 3rd element
You can make a constructor for class A which accepts a pointer to an object to class B and assign this pointer instead of allocating a new B:
A::A(B* b) : binst (b) {}
And in the construct of class B you pass 'this' in constructor of A:
B::B() : A(this) {}
The compiler will probably complain about it, but you can try. (It is ugly, though.)
Note that you can NOT use the binst pointer to access object B in A's constructor, because it's not fully constructed yet.
Does it actually need the binst as a member, or does it simply need to access it?
class B;
class A {
public:
B& binst(); //throws exception if not derived from B
A() {}
virtual ~A() {} //effectively required for the dynamic_cast
void foo();
};
class B : public A {
public:
void bar() {};
};
B& A::binst() {return dynamic_cast<B&>(this);}
void A::foo() {return binst().bar();}

Prevent class inheritance in C++

Recently one of my friend asked me how to prevent class inheritance in C++. He wanted the compilation to fail.
I was thinking about it and found 3 answers. Not sure which is the best one.
1) Private Constructor(s)
class CBase
{
public:
static CBase* CreateInstance()
{
CBase* b1 = new CBase();
return b1;
}
private:
CBase() { }
CBase(CBase3) { }
CBase& operator=(CBase&) { }
};
2) Using CSealed base class, private ctor & virtual inheritance
class CSealed
{
private:
CSealed() {
}
friend class CBase;
};
class CBase : virtual CSealed
{
public:
CBase() {
}
};
3) Using a CSealed base class, protected ctor & virtual inheritance
class CSealed
{
protected:
CSealed() {
}
};
class CBase : virtual CSealed
{
public:
CBase() {
}
};
All the above methods make sure that CBase class cannot be inherited further.
My Question is:
Which is the best method ? Any other methods available ?
Method 2 & 3 will not work unless the CSealed class is inherited virutally. Why is that ? Does it have anything to do with vdisp ptr ??
PS:
The above program was compiled in MS C++ compiler (Visual Studio).
reference : http://www.codeguru.com/forum/archive/index.php/t-321146.html
As of C++11, you can add the final keyword to your class, eg
class CBase final
{
...
The main reason I can see for wanting to do this (and the reason I came looking for this question) is to mark a class as non subclassable so you can safely use a non-virtual destructor and avoid a vtable altogether.
You can't prevent inheritance (before C++11's final keyword) - you can only prevent instantiation of inherited classes. In other words, there is no way of preventing:
class A { ... };
class B : public A { ... };
The best you can do is prevent objects of type B from being instantiated. That being the case, I suggest you take kts's advice and document the fact that A (or whatever) is not intended to be used for inheritance, give it a non-virtual destructor, and no other virtual functions, and leave it at that.
You are going through contortions to prevent further subclassing. Why? Document the fact that the class isn't extensible and make the dtor non-virtual. In the spirit of c, if someone really wants to ignore the way you intended this to be used why stop them? (I never saw the point of final classes/methods in java either).
//Note: this class is not designed to be extended. (Hence the non-virtual dtor)
struct DontExtened
{
DontExtened();
/*NOT VIRTUAL*/
~DontExtened();
...
};
1) is a matter of taste. If I see it correctly, your more fancy 2nd and 3rd solutions move the error in certain circumstances from link time to compile time, which in general should be better.
2) Virtual inheritance is needed to force the responsibility to initialize the (virtual) base class to the most derived class from where the base class ctor is no longer reachable.
To answer your question, you can't inherit from CBase because in virtual inheritance a derived class would need to have direct access to the class from which it was inherited virtually. In this case, a class that would derive from CBase would need to have direct access to CSealed which it can't since the constructor is private.
Though I don't see the usefulness of it all (ie: stopping inheritance) you can generalize using templates (I don't think it compiles on all compilers but it does with MSVC)
template<class T>
class CSealed
{
friend T; // Don't do friend class T because it won't compile
CSealed() {}
};
class CBase : private virtual CSealed<CBase>
{
};
If you can, I'd go for the first option (private constructor). The reason is that pretty much any experienced C++ programmer will see that at a glance and be able to recognize that you are trying to prevent subclassing.
There might be other more tricky methods to prevent subclassing, but in this case the simpler the better.
From C++11 onward, there is a clean solution that I am surprise not to see here. We can make the class final preventing any further inheritance.
class Foo final {};
class Bar: public Foo {}; // Fails to compile as Foo is marked as final
class myclass;
class my_lock {
friend class myclass;
private:
my_lock() {}
my_lock(const my_lock&) {}
};
class myclass : public virtual my_lock {
// ...
public:
myclass();
myclass(char*);
// ...
};
myclass m;
class Der : public myclass { };
Der dd; // error Der::dd() cannot access
// my_lock::my_lock(): private member
I found it here to give credit. I am posting here just other people can easily access
http://www.devx.com/tips/Tip/38482
To elaborate on Francis' answer: if class Bottom derives from class Middle, which virtually inherits from class Top, it is that most derived class (Bottom) that is responsible for constructing the virtually inherited base class (Top). Otherwise, in the multiple-inheritance/diamond-of-death scenario (where virtual inheritance is classically used), the compiler wouldn't know which of the two "middle" classes should construct the single base class. The Middle's constructor's call to the Top's constructor is therefore ignored when Middle is being constructed from Bottom:
class Top {
public:
Top() {}
}
class Middle: virtual public Top {
public:
Middle(): Top() {} // Top() is ignored if Middle constructed through Bottom()
}
class Bottom: public Middle {
public:
Bottom(): Middle(), Top() {}
}
So, in the the approach 2) or 3) in your question, Bottom() can't call Top() because it's inherited privately (by default, like in your code, but it's worth making it explicit) in Middle and thus is not visible in Bottom. (source)

C++ design question

Suppose I have a class Base which has a member variable A* my_hash.
I also have class Extended which inherits from class Base. I also have a class B
which extends A.
class Base{
Base(): my_hash(new A) {}
//methods which use my_hash
protected:
A* my_hash;
};
class Extended:public Base{
//methods which use my_hash from A
//I cannot have a B* my_other_hash in this class
//I would like to substitute B* my_hash
//I cannot let Base create my_hash (of type A*) because that is not what I want.
};
I would like Extended to do the usual (i.e. use everything it inherits from A), except
and with one important difference, I want my_hash to be B* instead of A*.
Whenever something accesses my_hash, either via Extended's methods or Base's methods,
I would like the methods to be executed to be B*'s.
One thing to try:
I cannot have a method call (e.g. create_hash() in Base()) which I redefine in Extended.
This does not work as there seems no way to go back up to the class Extended when I create the hash.
I would not like Base to even know about B. How do I do this?
If the type of 'B' extends 'A', then you could set it up so that you pass the value for 'm_hash' through the constructor (you can also hide this constructor as protected so code that doesn't inherit from 'Base' can't extend it).
e.g.
class Base{
Base(): my_hash(new A) {}
//methods which use my_hash
protected:
A* my_hash;
Base(A* hash): my_hash(hash) {}
};
class Extended:public Base{
public:
Extended() : Base(new B) {}
};
Also, if you want new, specialised functions in 'B' that you can call from 'Extended', then you can either store that in another pointer or just cast 'my_hash' to type 'B*'.
You could make the Base class into a template on A:
template<typename T>
class Base{
Base(): my_hash(new T) {}
//methods which use my_hash
protected:
T* my_hash;
};
class Extended:public Base<B>{
...
};
A template might be the way to go here, as suggested by Autopulated. Another way to do it is in fact to have a B* my_other_hash (like you mention in the question), and then in B's ctor set my_other_hash to my_hash.
class Extended:public Base{
ExtendedBase(): Base() {
my_other_hash = my_hash;
}
}
Then you can access the A methods in Base and the A or B methods in Extended. Make sure to only delete one of them! In Base's dtor or outside the hierarchy if you manage the memory elsewhere.