Скажем, у меня есть класс Face. Я хочу использовать композицию для построения Face. У лица есть глаза, поэтому я могу создать класс Eyes и использовать композицию, добавляющую глаза в Face.
Но что, если я подкласс глаза, например
class Eyes { ... };
class BlueEyes : public Eyes { ... };
class BrownEyes : public Eyes { ... };
? (Предположим, что все интерфейсы идентичны.)
Можно ли составить Face во время выполнения, скажем, в зависимости от какого-либо параметра, предоставленного конструктору, Face получит либо BlueEyes, либо BrownEyes?
Вы можете сделать это, составив указатель на базовый класс. Например.,
enum EyeColor{Blue, Brown}; // Even better would be enum class
class Face
{
private:
// Here is the composition - to a base-class ptr.
std::unique_ptr<Eyes> m_eyes;
public:
explicit Face(EyeColor c)
{
// Use c to instantiate m_eyes below to the appropriate-class object.
}
};
Фактически, реализация C ++ некоторых шаблонов проектирования, например, стратегия, часто использую это.
То, что вы ищете, это шаблон дизайна фабрики.
Ваша фабрика получает имя класса для создания экземпляра и все необходимые параметры, а затем создает экземпляр соответствующего подкласса. Имя может принимать форму строки, перечислимого типа или любого другого средства выбора подходящего подкласса. Давайте использовать строку:
Eyes *create_eyes(const std::string &color)
{
if (color == "blue")
return new BlueEyes;
if (color == "brown")
return new BrownEyes;
throw "Unknown eye color";
}