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.
Related
How can I possibly do this:
class Base
{
public:
int a, b, c;
void function();
...
};
class Derived1 :
private Base
{
public:
int d, e, f;
...
};
class Derived2 :
private Base
{
public:
void addObject(const Base* obj);
...
};
Note that I inherit it as private
Then I would like to do like:
Base* d1 = new Derived1();
Base* d2 = new Derived2();
d2->addObject(d1);
And here is the relevant issue I am getting from the compiler:
C:\test\test.cpp||In function 'void init()':|
C:\test\test.cpp|423|error: no matching function for call to 'Derived2::addObject(const Base*)'|
C:\test\test.cpp|423|note: candidate is:|
C:\test\test.h|29|note: void Derived2::addObject(const Base*)|
C:\test\test.h|29|note: no known conversion for argument 1 from 'Derived1 {aka ... }' to 'const Base* {aka ... }'|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 9 seconds) ===|
The reason I want to inherit the Base as private by some derived classes is to hide some Base's members/functions in public scope.
I do not want to directly access some Base::functions() in a public scope but else, used a Derived::function() instead to manipulate its data members and let the derived class decide what action it would perform.
However, I could think of overriding each function from base class that I do not want to modify directly in public scope but its not flexible and too many in my case.
What I mean is:
class Base
{
public:
//I must think in advance deciding whether if it'll be virtual or not.
[virtual] void f1(int);
[virtual] void f2(int);
[virtual] void f3(int);
//and many more...
};
class Derivedn :
private Base
{
public:
//hmm, I should not neglect to override certain base' member functions
//that I don't want to access in public scope.
void f1(int);
};
I want to avoid this but...
Is there any other way I can do, similar to this one, without overriding each Base::function()s?
The reason this does not work is that inheriting privately does not constitute an "is a" relationship. In fact, is a lot closer to composition than inheritance, because the derived class acquires the implementation of the base without acquiring its interface.
The reason I want to inherit the Base as private by some derived classes is to hide some Base's members/functions in public scope.
That is a wrong reason to inherit privately. Here are some good answers to the question when you should inherit privately.
Is there any other way I can do, similar to this one, without overriding each Base::function()s?
You are not required to override every single one of the Base's functions, unless they are pure virtual (also known as "abstract") ones. Your base class can provide empty implementations for its virtual functions, so that the derived classes could decide which functionality to provide.
I think your code should read:
d2.addObject(&d1); // Note the "&"
As the compiler says, there is no possible conversion from an instance of Derived1 to a const pointer to an instance of Base.
Not sure what you wanna, but polymorphism do exactly that, allow you to override a base function in Derived class:
class Base
{
public:
int a, b, c;
virtual void function();
^^^^^^^
...
};
class Derived1 :
public Base
{
public:
int d, e, f;
virtual void function(); // do derived version of Base::function
};
and now you can access Derived version of function from Base objects
Can someone explain why this code doesn't work.
class A
{
public:
A(void){}
virtual ~A(void){}
protected:
A* parent;
};
class B : public A
{
public:
B(void){parent = new B;}
~B(void){delete parent;}
protected:
int a;
};
class C : public B
{
public:
C(void){}
virtual ~C(void){}
void f(void){ ((B*)parent)->a; }
};
How is it possible that C isn't able to access members of B?
If I convert parent to a C* in stead of a B* it works fine. But I don't want users to take any unnecessary risks. Is there a cleaner way access a?
Thanks.
From an object of the C class, you can access protected members of B, but only if they're part of some object of class C (maybe yours, maybe not). In other words, to access a from C, you need a pointer (or a reference) to C. This is what the protected modifier means.
The reason for this is the following. The ((B*)parent) pointer may point to some other subclass of B, completely different from C, and that subclass may have the a member inaccessible.
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;
};
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();}
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.