Вопрос проектирования C ++ - PullRequest
1 голос
/ 21 декабря 2009

Предположим, у меня есть класс Base, в котором есть переменная-член A * my_hash. У меня также есть класс Extended, который наследуется от класса Base. У меня тоже есть класс B который расширяет 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.
};

Я бы хотел, чтобы Extended делал обычное (т.е. использует все, что он наследует от A), кроме и с одним важным отличием я хочу, чтобы my_hash был B * вместо A *.
Всякий раз, когда что-то обращается к my_hash, через методы Extended или Base, Я хотел бы, чтобы выполняемые методы были B *.

Одна вещь, чтобы попробовать: У меня не может быть вызова метода (например, create_hash () в Base ()), который я переопределяю в Extended. Это не работает, так как, кажется, нет никакого способа вернуться к классу Extended при создании хэша.

Я бы не хотел, чтобы Бейс даже знал о Б. Как мне это сделать?

Ответы [ 3 ]

4 голосов
/ 21 декабря 2009

Если тип «B» расширяет «A», то вы можете настроить его так, чтобы передать значение для «m_hash» через конструктор (вы также можете скрыть этот конструктор как защищенный, чтобы код, который не наследовал, из базы не может его расширить).

, например

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) {}
};

Кроме того, если вам нужны новые специализированные функции в «B», которые вы можете вызывать из «Extended», то вы можете либо сохранить их в другом указателе, либо просто привести my_hash к типу «B *».

2 голосов
/ 21 декабря 2009

Вы можете превратить Базовый класс в шаблон на 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>{
 ...
};
0 голосов
/ 21 декабря 2009

Шаблон может быть подходящим способом, как предлагает Autopulated. Другой способ сделать это - фактически иметь B * my_other_hash (как вы упомянули в вопросе), а затем в ctor B установите my_other_hash в my_hash.

class Extended:public Base{
    ExtendedBase(): Base() {
        my_other_hash = my_hash;
    }
}

Затем вы можете получить доступ к методам A в Base и методам A или B в Extended. Обязательно удалите только один из них! В dtor базы или вне иерархии, если вы управляете памятью в другом месте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...