Могу ли я переопределить член абстрактного базового класса?

0

Я не уверен, правильно ли формулирую этот вопрос, поэтому я просто начну с кода. Это не из моей программы, но, надеюсь, ее достаточно, чтобы понять концепцию.

class AbstractClass {

public:
    typedef std::unique_ptr<AbstractClass> Ptr;
    std::vector<Ptr> mChildren;
    void AddChild(Ptr child);
    void Render();
}


class Derived {

public:
typedef std::unique_ptr<Derived> Ptr;
std::vector<Ptr> mChildren;

private:
void CheckChildren();
}

Как вы можете видеть, я по существу "переопределяю" абстрактный класс "mChildren". Это отлично работает для моего метода Render(), который использует mChildren для рекурсивного рендеринга всех детей. Однако, когда я пытаюсь вызвать CheckChildren() из производного класса, mChildren отображается как пустой.

Это после вызова

AddChild(std::move(new Derived));

метод тоже. Дело в том, что мой метод Render отлично работает, а это значит, что mChildren не пуст. Похоже, что я не могу правильно видеть коллекцию из моего производного класса. Я уверен, что это, вероятно, в основном проблема с неправильным инкапсулированием детей, но я не понимаю, как решить эту проблему.

Будет ли держать mChildren в качестве частной помощи члена? Я просто попробовал позволить mChildren быть закрытым и создать getter, который вернул указатель на вектор, но VS не разрешил бы моему getter getter возвращать указатель на вектор производных классов.

Подводя итог - мне нужно иметь доступ к коллекции, так как это было все AbstractClass :: Ptr, но мне нужно иметь возможность модифицировать Derived :: Ptr как производный объект с большим количеством методов.

  • 1
    Если вы намереваетесь просто использовать один m_Children, тогда удалите 'std :: vector <Ptr> mChildren;' из производного класса. (Также ваш класс на самом деле не является производным)
Теги:
polymorphism

2 ответа

2

Вы не можете переопределять элементы данных в C++, а только виртуальные функции.

  • 0
    +1 верно. Я не упомянул об этом, потому что полагал, что OP просто подразумевает использование члена базового класса в производном классе. Как я уже упоминал, и, как я уверен, вы знаете, почти весь код в вопросе неверен.
2

Есть несколько проблем с вашим кодом - я не могу уйти от них (нет времени) -but:

class Derived {

public:
....
std::vector<Ptr> mChildren;

Это не "переопределение" - у вас есть REDECLARED mChildren - это другой экземпляр, чем тот, который находится в вашем "абстрактном классе" (он не очень абстрактный, но это другая история) - поэтому, когда вы вызываете его из базового класса, вы 'Получить член из базового класса, но когда вы вызываете его из производного класса, вы получите РАЗЛИЧНЫЙ член - тот из производного класса.

Кроме того, я не уверен точно, как вы используете этот код, но ваш производный класс здесь не выводится - это совсем другой класс:

попробуй это:

class AbstractClass {

  public:

    typedef std::unique_ptr<AbstractClass> Ptr;
    void AddChild(Ptr child)

  protected:
   std::vector<Ptr> mChildren;

...

}

class Derived: public AbstractClass{...

Не переопределяйте mChildren в производном классе. Когда вы объявляете его защищенным в базовом классе, он "живет" в базовом классе, но тот же член доступен из производного класса. Это должно решить вашу проблему.

Но вам нужно прочитать модификаторы доступа, абстрактные методы, виртуальные методы и наследование. Любая достойная книга C++ или онлайн-учебник помогут вам в этом.

  • 0
    Извините, я набрал этот код и не скопировал его из моей программы. Мой производный класс наследуется от моего абстрактного базового класса. Моя проблема в том, что мой базовый класс не поддерживает все методы, которые мне нужны для поддержки производного класса. Производный класс должен содержать члены, которые являются DerivedClasses, но также должен иметь возможность выполнять основные функции, которые есть в моем базовом классе. Это дилемма. Например: представьте себе базовый класс Bodypart. Кость, Запястье и Голова - все необходимо сделать (). Тем не менее, кости могут иметь детские Bodyparts, запястье может иметь кости и т. Д ..
  • 0
    @ user1781726 - затем вы объявляете render () в базовом виртуальном и выполняете то, что является общим для всех классов, а затем переопределяете его в производных классах для выполнения дополнительных действий. Смотрите Полиморфизм - для полного учебника.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню