2016-02-26 4 views
1

Я хотел бы включить объект Composed в свой класс Base и иметь разные производные классы, имеющие разные конфигурации. Однако класс Composed требует параметра в конструкторе, и у меня нет контроля над его архитектурой.Как инициализировать объекты-члены, которым требуются параметры конструктора в производных классах?

Компилятор сообщает об ошибке, поскольку параметр для Composed должен быть передан при инициализации класса Base. Но я хочу, чтобы он был инициализирован в производных классах. Что мне делать в этом случае?

class Base{ 
    public: 
    Base(); //Error 
    protected: 
    Composed comp; 
}; 
class Composed{ 
    public: 
    Composed(int id):id(id); 
    private: 
    int id; 
}; 
class Derived_1:public Base{ 
    public: 
    Derived():comp(1234){}; 
};  
class Derived_2:public Base{ 
    public: 
    Derived():comp(2345){}; 
}; 
+1

Должен ли 'Base' даже иметь конструктор? Можно ли сделать это виртуальным? Если он имеет элемент «Составленный», но не инициализирует его, используется ли какой-либо объект «Base»? – Biffen

+0

Делает здравый смысл! Можете ли вы привести пример кода? –

+0

Что? Несущий конструктор? – Biffen

ответ

4

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

class Composed{ 
    public: 
    Composed(int id):id(id); 
    private: 
    int id; 
}; 
class Base{ 
    public: 
    Base(int id):comp(id){} 
    protected: 
    Composed comp; 
}; 
class Derived_1:public Base{ 
    public: 
    Derived():Base(1234){}; 
};  
class Derived_2:public Base{ 
    public: 
    Derived():Base(2345){}; 
}; 
+0

Глупый! Забыл все основы. Благодаря! :) –

1

Есть несколько вариантов. Наиболее простым является передача объектов, необходимых для сборки Comp для конструктора класса Base.

class Base{ 
    public: 
    Base(int id):comp(id){} 
protected: 
    Composed comp; 
}; 

class Derived_1:public Base{ 
    public: 
    Derived():Base(1234){} 
};  
class Derived_2:public Base{ 
    public: 
    Derived():Base(2345){} 
}; 

Другая возможность - не включать Comp в базовый класс. Поместите его в каждый производный класс. Вы можете добавить чистую виртуальную функцию в класс Base, который возвращает Comp (или его адрес).

Еще одна опция - сохранить указатель на Comp (возможно, unique_ptr) и выделить его в производных классах.

2

Представьте, что вы построили объект Base. Как он узнает, какой параметр должен пройти к конструктору comp? Класс Base в корне ошибочен, поэтому у вас есть ошибка. Он должен знать, как построить объект-объект Composed.

Вы можете добавить конструктор по умолчанию для Composed, а затем изменить этот объект в Derived_1 и Derived_2. В качестве альтернативы, как и другие, вы можете сделать конструктор Base, используя параметры для построения comp. Это звучит предпочтительнее для меня, но это зависит от вашего варианта использования.

Помните, что при построении Derived_1 или Derived_2 класс Base является первым, что создано перед другими переменными-членами.