c++:Динамически выбирать, какой подкласс создавать
Вопрос
Я новичок в c ++, и у меня есть вопрос.
Допустим, у нас есть базовый класс Base и два производных класса, Derived1 и Derived2.е.е.Derived1 имеет конструктор, принимающий целое число, а Derived2 - конструктор, принимающий логическое значение.
Можно ли определить во время выполнения (или во время компиляции), какой из этих двух подклассов создать, и назначить его базовому классу.
Что- то вроде этого:Основание b = ???(значение), где значение имеет тип integer или boolean.
Заранее спасибо!
Решение
Вы, вероятно, хотите Шаблон заводского дизайна.
Другие советы
Напишите две перегрузки вызываемой функции createMyBlaBla
.Один принимающий int
, а другой , принимающий bool
.Каждый возвращает желаемый тип производного класса.например ,:
Base* create(int n)
{
return new Derived1(n);
}
Base* create(bool b)
{
return new Derived2(b);
}
....
Base* b1 = create(10); // Derived1
Base* b2 = create(false); // Derived2
Люди называют это фабричным шаблоном.
Я действительно не думаю, что это возможно так, как вы хотите, чтобы это было, полиморфизм в C ++ просто так не работает.
Если я правильно понял, вы хотите, чтобы переменная объявлялась как Base decids, в зависимости от типа параметра, будет ли она Derived1 или Derived2, и все это без использования заводского шаблона.
Причина, по которой это невозможно, заключается в том, что Base
класс на самом деле не осознает существования своего Derived
классы, ни вы можете объявить переменную стека и заставить ее "вести себя" как производный класс.Тем не менее, я могу предложить обходной путь, но опять же, это
не удовлетворяет всем ожиданиям от реальной иерархии классов, которую вы
хотите (если вы действительно этого хотите_:
class Facade{
public:
Facade(int foo) : b(new Derived1(foo)){}
Facade(bool foo) : b(new Derived2(foo)){}
Base Value()
{
return *b;
}
private:
Base* b;
};
И тогда вы можете сделать что-то вроде:
Facade foo(10);
Facade bar(true);
int x = (reinterpret_cast<Derived1*>(foo.Value())) -> val;
bool y = (reinterpret_cast<Derived2*>(bar.Value())) -> val;