@RadioRedFox
Java, Android, Python, SQL

Можно ли в С++ стрингу преобразовать в тип?

Есть родительский класс функция
class function
{
public:
function (const string &Name) name(Name) {}
virtual double get_out (const double x) const =0;
string name;
};


И есть куча классов которые наследуют этот класс переопределяя метод get_out
например:
class sinus : public function
{
sinus () :  function("sinus")
double get_out (const double x) { return sin(x);}
}


Далее мне нужно в зависимости от названия функции создать функцию
У каждой функции имя совпадает с название класса.
function * get_function (const string name)
{
if (name == "sinus")
    retrun new sinus();
}


Есть ли способ как то избежать огромного стека ifфов ? Чтобы не создавать под каждую функцию свой if, а преобразовать строку "sinus" в тип sinus?
  • Вопрос задан
  • 163 просмотра
Решения вопроса 2
zagayevskiy
@zagayevskiy
Android developer at Yandex
В С++ нет такого способа. Но можно завести мапу стрингов к фабрикам функций, зарегистрировать в ней все функции, и по имени доставать.
Ответ написан
Комментировать
tsarevfs
@tsarevfs Куратор тега C++
C++ developer
Хорошего способа сделать этого нет.

Паттерн который позволяет избавиться от if-ов называется Factory. Есть разные способы его реализации. Основная идея в том, что есть класс FunctionFactory который хранит map name->createFunc. Где createFunc это функция которая создает нужный экземпляр. Но этот map тоже нужно заполнить, поэтому совсем не писать лишний код не получится.
Это все безобразие позволяет не иметь огромной функции которая знает про все зарегистрированные классы.

Тут есть пример правильного кода
https://dzone.com/articles/factory-with-self-regis...
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@vanyamba-electronics
template <class _T>
class FunctionT : public function
{
public:
    static const char m_name[];
    function* get_function(const string& name) {
        if (name == m_name)
            return new _T;
        return nullptr;
    }
};

using namespace std;

vector<function*> functions;
functions.push_back( new FunctionT<sinus> );
functions.push_back( new FunctionT<cosinus> );
functions.push_back( new Function<tangens> );

for(vector<function*>::iterator it = functions.begin(); it != functions.end(); ++it) {
    function* f = (*it)->get_function("sinus");
    if ( f != nullptr )
          f->get_out();
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы