2016-10-10 9 views
2

Предположим, у меня есть два класса, полученные из одного базового класса. Я хочу создать экземпляр нового объекта класса в зависимости от ввода командной строки. Я мог бы это сделать:C++ Построить класс по строке

#include <iostream> 
#include "DerivedClass1.h" 
#include "DerivedClass2.h" 
using namespace std; 

int main(int argc, char *argv[]) 
{ 
    if (argv[1] == "DERIVED CLASS 1") { 
     DerivedClass1 *myClass = new DerivedClass1(argv[2]); 
     myClass->doSomething(); 
    } else if (argv[1] == "DERIVED CLASS 2") { 
     DerivedClass2 *myClass = new DerivedClass2(argv[2]); 
     myClass->doSomething(); 
    } 
} 

Но мне было интересно, есть ли более элегантный способ сделать это. Я думаю о создании фабрики абстрактного класса, или hard-code отображает имена строк в экземплярах класса. Пара ограничений

1) Мой базовый класс является абстрактным - она ​​содержит чисто виртуальные функции

2) Я могу назвать только параметризованные конструкторы

+2

'argv [1] ==" DE RIVED CLASS 1 "является ошибкой –

+0

Вам придётся создать шаблон фабричного дизайна. Эта ссылка может быть полезной https://sourcemaking.com/design_patterns/factory_method/cpp/1 –

+0

@ M.M что с этим не так? – jjiang

ответ

8

функция завод должен работать нормально:

BaseClass* create(std::string const& type, std::string const& arg) 
{ 
    // Could use a map or something instead if there are many alternatives 
    if (type == "DERIVED CLASS 1") 
     return new DerivedClass1(arg); 
    else if (type == "DERIVED CLASS 2") 
     return new DerivedClass2(arg); 
    else 
     return nullptr; // Or throw an exception or something else 
} 

Использовать как

BaseClass* ptr = create(argv[1], argv[2]); 
+0

Почему тип должен быть строкой const &? – jjiang

+1

@ahhhhhjulie Вам не нужно указывать ссылку на постоянный объект string, просто простая 'std :: string' должна работать в вашей ситуации. Однако, если вы хотите называть его другими строками, передача ссылки означает меньшее копирование. Передача ссылки на константу означает, что вы можете передать строковый литерал или временный объект, а также сообщить компилятору, что функция не будет изменять функцию, которая может включать некоторые оптимизации (в данном случае это вряд ли) и упростить ее семантическую проверку. –