创建一个类名作为模板参数

时间:2016-06-08 06:29:02

标签: c++ templates

我必须创建许多业务对象(每个客户端都应该拥有自己的类)。理想情况下,我希望能够通过客户端内部标记Client::getName(void)访问该类,因此我创建了一个实现此目的的宏。

#define CLIENT_CLASS(classname) \
class classname : public Base \
{ \
public: \
    classname(void); \
    ~classname(void) {}; \
public: \
    static const std::string name; \
    static ClientId ID(void) { return CID_##classname; } \
    static Base *createInstance(void) { return new classname(); } \
private: \
    typedef Base super; \
}

最初我把它作为每个类单独复制,但我自然希望有一些可以根据需要编辑的东西。我本来希望将其作为模板实现,但我不确定这是否可行,因为我没有看到任何方法在模板中指定类名,而AFAIK无法在模板中定义静态方法?或者我错了,确实有办法将其转换为适当的模板吗?

CLIENT_CLASS_BODY是另一个宏,它基本上看起来像另一个宏,但包含公共类体的定义(如果可以将其模板化,可以将其移动到模板中)。

工厂看起来像这样:

包括

namespace va {
    CLIENT_CLASS(client1);
    CLIENT_CLASS(client2);
    ....
}

的cpp

namespace va {
    CLIENT_CLASS_BODY(client1);
    CLIENT_CLASS_BODY(client2);
    ...
}

#define CREATE_CLIENT(classname) addKey(classname::name, classname::ID(), classname::createInstance())

void ClientFactory::initClientMap(void)
{
    CREATE_CLIENT(va::client1);
    CREATE_CLIENT(va::client2);
    ...
}

1 个答案:

答案 0 :(得分:0)

使用模板,它应该类似于:

template <ClientId Id, const char* Name>
class TClient : public Base
{
public:
    TClient() {}
    ~TClient() {}
public:
    static const std::string name;
    static ClientId ID() { return Id; }
    static Base *createInstance() { return new TClient(); }
private:
    using super = Base;
};

template<ClientId Id, const char* Name> const std::string TClient<Id, Name>::name = Name;

然后

static constexpr char Client1Name[] = "Client1";
using Client1 = TClient<1, Client1Name>;

Demo

以同样的方式,

#define CREATE_CLIENT(classname) addKey(classname::name, classname::ID(), classname::createInstance())

应该是

template <typename T>
void ClientFactory::CreateClient()
{
    addKey(T::name, T::ID(), T::createInstance());
}

然后

void ClientFactory::initClientMap()
{
    CreateClient<va::client1>();
    CreateClient<va::client2>();
    //...
}