Я не уверен, правильно ли формулирую этот вопрос, поэтому я просто начну с кода. Это не из моей программы, но, надеюсь, ее достаточно, чтобы понять концепцию.
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 как производный объект с большим количеством методов.
Вы не можете переопределять элементы данных в C++, а только виртуальные функции.
Есть несколько проблем с вашим кодом - я не могу уйти от них (нет времени) -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++ или онлайн-учебник помогут вам в этом.