其他类的初始化类 - C ++ [英] Initialization class for other classes - C++

查看:110
本文介绍了其他类的初始化类 - C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想初始化2个类(例如Class ARegister,Class BRegister)注册一些值(A,B)。我想从一个超级(?)类(比如RegisterALL)初始化这两个类。

I would like to initialize 2 classes(say Class ARegister, Class BRegister) that registers some values(A,B). I want to initialize these two classes from a super(?) class( say Class RegisterALL).

例如:RegisterALL类将初始化ARegister和BRegister。所以任何使用模块的人都不需要单独创建ARegister和BRegister的对象,而是可以创建RegisterALL的对象。

Ex: RegisterALL class will initialize ARegister and BRegister. So anybody using the module need not create objects of ARegister and BRegister individually, instead they can create object of RegisterALL.

我想在构造函数中执行所有这些注册。所以需要做的是创建RegisterALL类的对象,并且注册会自动进行。

I would like to do all these registrations in the constructor. So all that needs to be done is to create objects of the RegisterALL class and the registrations happens automatically.

我们不在项目中使用异常。所以如果在注册中有一些错误,那么它是不可能知道。

We do not use exceptions in our project. So If there is some error in the registration then it is not possible to know.

我应该有单独的成员函数来做注册还是让构造函数做注册。

Should I have separate member function that will do the registration or let the constructor do the registration.

我是OO设计的新手。我觉得设计有问题,如果你能指出正确的方法,将会很有帮助。

I am a newbie to OO design. I feel something is wrong with the design, it will be helpful if you can point to the right approach.

推荐答案

做到这是使用CRTP(好奇地重复模板模式),派生类ARegister和BRegister自己作为模板参数传递给基类RegisterALL。
它将如下所示:

the best way do to this is using CRTP (curiously recurring template pattern), the derived classes ARegister and BRegister pass themselves as template arguments to the base class RegisterALL. It will look like this:

class RegisterAll
{
public:
    template<class DerivedType>
    DerivedType *createType()
    {
        RegisterAll *r = (*(m_creators[DerivedType::id]))();
        return dynamic_cast<DerivedType *>(r); //static_cast will work too if you didn't make a mistake
    }
protected:
    static std::map<int,RegisterAll *(*)()> m_creators;
};

std::map<int,RegisterAll *(*)()> RegisterAll::m_creators = std::map<int,RegisterAll *(*)()>();

template<class Derived>
class CRTPRegisterAll : public RegisterAll
{
public:
    static bool register() 
    {
        RegisterAll::m_creators.push_back(std::make_pair(Derived::id,Derived::create);
        return true;
    }

private:
    static bool m_temp;
};

template<class Derived>
bool CRTPRegisterAll<Derived>::m_temp = CRTPRegisterAll<Derived>::register();

class RegisterA : public CRTPRegisterAll<RegisterA>
{
private:
    static RegisterA *create() 
    {
        //do all initialization stuff here
        return new RegisterA;
    }

public:
    static const int id = 0;
};

现在, CRTPRegisterAll 中的静态变量 m_temp 的初始化将每个派生类型的创建者函数 RegisterAll 的列表。通常不是很好的设计有 RegisterAll 知道所有派生类非常可扩展)。这样,实际的创建方法可以在每个派生类中实现,创建器函数将自动注册在 RegisterAll 中。 CRTP的一个主要优点是派生类不需要知道如何将自己注册到基类的列表,这是为它们做的。至于错误处理也可以在每个派生类的创建器函数中实现。有更好的方法来处理id问题,但我不想在这里。
如果你想要一个更简单的方法,我建议阅读关于工厂设计模式。

Now the initialization of the static variable m_temp in CRTPRegisterAll pushes a creator function for each derived type onto RegisterAll's list. It is generally not very good design to have RegisterAll know about all the derived classes (it isn't very extensible). This way the actual creation method can be implemented in each derived class and the creator function will be automatically registered in RegisterAll. One of the main advantages of CRTP is that the derived classes don't need to know how to register themselves to the base class' list, it is done for them. As for error handling that too can be implemented in each derived class' creator functions. There are better ways to handle the id issue but I don't want to get into that here. If you want a simpler method I suggest reading about the Factory design pattern.

这篇关于其他类的初始化类 - C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆