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 wa开发者_如何学JAVAy 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.
精彩评论