2016-06-23 2 views
1

У меня есть заводская функция C++, которая будет использоваться для создания экземпляров определенных конкретных классов, которые происходят из какого-то абстрактного класса.Пометка экземпляров класса C++ с метаданными

С точки зрения кода, фактические английские названия этих конкретных классов не важны. Скажем, что это разные типы «Событие», полученные из класса «AbstractEvent». Для функции кода фактические имена производных классов не имеют значения, так как все они будут иметь какой-то уникальный числовой идентификатор, сгенерированный при создании экземпляра, который будет таким, как другие модули будут ссылаться на них, что будет работать только с ссылки на абстрактный тип, а не конкретный конкретный класс.

С точки зрения обслуживания кода, было бы полезно, чтобы кодер знал, скажите, что определенный класс или метод принял «FooEvent», с шаблоном для работы с int или «BarEvent», с шаблоном для работы с float, поэтому есть некоторый понятный для человека термин, с которым работает пользователь при использовании API.

Есть ли «канонический» способ достичь этого? Было бы предпочтительнее, если бы решение не создавало накладных расходов во время выполнения.

+0

Вот что комментарии для. Вы можете составить стандартизованный раздел комментариев, который можно использовать для ваших классов. –

+0

Вы можете использовать 'SFINAE' для включения/отключения разделов API, основанных на типе события. Не может быть самым читаемым, но он не будет компилироваться, если они сделают это неправильно. – lcs

+0

, пожалуйста, напишите минимальную полную программу, которая демонстрирует, как вы думаете, что она может работать. то мы можем сказать вам, есть ли лучший способ. –

ответ

1

как насчет constexpr идентификатора строки:

#include <iostream> 
#include <string> 
#include <memory> 

struct EventBase 
{ 
    virtual const std::string& type() const = 0; 
    virtual ~EventBase() = default; 
}; 

template<const char* type_name> 
struct EventModel : EventBase 
{ 

    const std::string& type() const override { 
     static const std::string _ { type_name }; 
     return _; 
    } 
}; 

constexpr char hello[] = "hello"; 
constexpr char world[] = "world"; 

int main(int argc, const char * argv[]) { 

    auto p1 = std::make_unique<EventModel<hello>>(); 
    auto p2 = std::make_unique<EventModel<world>>(); 

    std::cout << p1->type() << std::endl; 
    std::cout << p2->type() << std::endl; 
    return 0; 
} 

теперь у вас есть несколько вариантов для выбора типов сообщений:

bool is_hello_slow(const EventBase& e) 
{ 
    return e.type() == hello; 
} 

bool is_hello_medium(const EventBase* pe) 
{ 
    return dynamic_cast<const EventModel<hello>*>(pe); 
} 

template<class Event> 
bool is_hello_compile_time(const Event&) { 
    return std::is_base_of<EventModel<hello>, Event>(); 
} 
+0

Да! Это именно то, что я имел в виду - возможность шаблонов конкретных событий с английскими обозначениями. – Bitrex

Смежные вопросы