开发者

C++ design question

开发者 https://www.devze.com 2022-12-14 07:33 出处:网络
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

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消