Как получить ссылку / указатель на класс (не объект)? - PullRequest
0 голосов
/ 31 октября 2019

У меня есть std::map, где key равно string, и я хочу, чтобы value был не объектом, а reference/pointer to a class, который я могу создать.

std::map<::std::string, ?class_reference?> handlers_;

После выбора конкретной записи я хочу создать экземпляр класса и выполнить функцию-член.

Ответы [ 2 ]

1 голос
/ 01 ноября 2019

Как уже упоминали другие, если вы хотите создать соответствующие объекты через строку (например, имя класса), вам нужно будет использовать фабричный шаблон, который может создавать связанные объекты (тот же базовый класс). Вот простой пример, который легко понять (вы просто храните лямбду, которая возвращает объекты на карте):

#include <map>
#include <string>
#include <functional>
#include <iostream>

class Base {};

class A : public Base{
    public:
    A() { std::cout << "A ctr" << std::endl; }
};

class B : public Base {
    public:
    B() { std::cout << "B ctr" << std::endl; }
};

int main() {
    std::map<std::string, std::function<Base*()> > m;
    m["a"] = []() { return new A(); };
    m["b"] = []() { return new B(); };
    m["a"]();
    m["b"]();

}
0 голосов
/ 01 ноября 2019

Как получить ссылку / указатель на класс (не объект)?

Короткий ответ, вы не можете. К сожалению, C ++ не работает таким образом.

Однако, чтобы решить вашу конкретную проблему, у вас есть опция фабричного шаблона , который будет выглядеть примерно так:

template <class T>
class factory {
    public:
        virtual std::unique_ptr<T> createObject() = 0;
};

class base { // some base class common to all the types you are intending to create

};

class foo : public base { // some class you want to create

};

class fooCreator : public fatory<base> {
    public:
        std::unique_ptr<T> createObject() {
            return someUniquePointerToANewObject;
        }
}


int main() {
    std::map<std::string, std::unique_ptr<factory<base>>> myMap; // because we are creating some bases

    myMap["some key"] = new myFooCreator;

    // now let's create some new `base`
    if(myMap.find("some matching key") != myMap.end()) {
        std::unique_ptr<base> myBaseObject = myMap["some matching key"]->createObject();

        // use created object
    }

    return 0;
}

Конечно, здесь есть много вещей, которые могут пойти не так, например, если по какой-то причине вы нажмете nullptr на myMap. Но, по крайней мере, у вас есть представление о том, как это выглядит сейчас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...