2015-07-26 2 views
2

У меня есть класс, который мне нужно инициализировать:Как инициализировать родителя с помощью члена дочернего элемента?

//Parent.h 
class Parent { 
public: 
    Parent(Image image); 
private: 
    const Image parentImage; 
} 

//Parent.cpp 
Parent::Parent(Image image) : parentImage(image) {} 

//Child.h 

#import "Parent.h" 

class Child : public Parent { 
public: 
    Child(int c); 
private: 
    Camera childCamera; 
} 

//Child.cpp 
Child::Child(int c) : Parent(this->childCamera.getImage()), childCamera(c) {} 

В Camera необходимо инициализировать, прежде чем изображения могут быть извлечены из него. В Parent хранится изображение с камеры, которое находится const, ребенок хранит Camera. Как создать Child? Я не могу изменить Parent, так как существуют другие подклассы, которые инициализируют Parent другими способами. Я могу изменить Child, но Camera не может быть скопирован, а Child необходимо сохранить Camera.

EDIT: Я мог бы добавить конструкторы в Parent, если это самое чистое решение.

+0

что такое 'this-> childDataSource.getImage()'? Ваш код не показывает зависимости между 'childCamera' и' Parent' – David

+0

Извините, должен быть 'this-> childCamera.getImage()'. В реальной ситуации есть еще много членов и т. Д., Я сделал ошибку при упрощении. – Drew

+4

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Base-from-Member – Columbo

ответ

0

Вы не можете этого сделать.

В соответствии со стандартом (12.6.2/10) порядок инициализации:

- (...)

- Тогда прямые базовые классы инициализируются в декларации порядке, как они отображаются в списке-спецификаторе-базе (независимо от порядка запоминающих устройств-мишеней ).

- Затем нестатические элементы данных являются , инициализированными в том порядке, в котором они были объявлены в определении класса (опять же независимо от порядка ввода-инициализаторов).

- И наконец, выполнен составной оператор тела конструктора.

Так что в вашем Child конструктора списка MEM-инициализации для Parent инициализатора вы не можете ничего, что полагается на Child переменных член, потому что они неинициализированные в тот момент использования.

Вы могли бы, однако использовать аргументы конструктора ребенка, например:

Child::Child(int c) : Parent(c.getImage()), childCamera(c) {} 

при условии, конечно, что каждая копия объекта Camera будет возвращать то же изображение, что и исходный объект.

Другой альтернативой может быть использование множественного наследования из вспомогательного класса (для использования второго тире стандартной цитаты выше). Но это я нахожу сложным и в любом случае также потребует копию объекта камеры.

0

Учитывая все ограничения по дизайну, которые вы указали, одним из разумных решений было бы создание камеры снаружи для ребенка, а затем передача ее в конструктор Child. Тогда ребенок возьмет на себя ответственность за это.

Так класс может быть записан как:

class Child : public Parent { 
public: 
    Child(Camera* camera); 
private: 
    std::unique_ptr<Camera> childCamera; 
} 

//Child.cpp 
Child::Child(Camera* camera) 
    : Parent(camera->getImage()), childCamera(camera) 
{} 

А затем используется в качестве:

Camera* camera = new Camera; 
Child child(camera); 
+0

Было бы лучше, если бы конструктор 'Child' взял' unique_ptr '. – aschepler

0

нет, вы не можете.вы не можете использовать ничего, что полагается на Child for Parent.

Смежные вопросы