Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 执行类型转换的中介模板_C++_Templates_Observer Pattern - Fatal编程技术网

C++ 执行类型转换的中介模板

C++ 执行类型转换的中介模板,c++,templates,observer-pattern,C++,Templates,Observer Pattern,我正在评估观察者模式的实现策略,其中一个要求是基本主题类在事件类的派生(具体)类中实现方法 在原型实现中,我在具体事件类中获得了以下代码: // a concrete event class evZoom : public AbstractEvent { public: virtual void Fill( Subject *aZoomManager) { mRatio = dynamic_cast<ZoomManager *>(aZoomManage

我正在评估观察者模式的实现策略,其中一个要求是基本
主题
类在
事件
类的派生(具体)类中实现方法

在原型实现中,我在具体事件类中获得了以下代码:

// a concrete event
class evZoom : public AbstractEvent
{
public:
    virtual void Fill( Subject *aZoomManager)
    {
        mRatio = dynamic_cast<ZoomManager *>(aZoomManager)->mRatio;
    }

    int mRatio;
};
//一个具体的事件
类evZoom:公共抽象事件
{
公众:
虚拟空白填充(主题*AzoManager)
{
mRatio=动态施法(AzoManager)->mRatio;
}
国际货币基金组织;
};
现在,我为每个concreate事件都必须执行这种类型的强制转换而烦恼

换句话说,我关心代码的简单性和简洁性,我更喜欢具体的类(其中有很多)来拥有更优雅的代码,用更复杂的基类代码(其中有一个)来交换

因此,我提出的解决方案是使用一个中介(即基类和具体类之间的中介)模板来进行类型转换

完整的实现如下所示:

// For Dec
class Subject;

// A non template abstract base class for the Subject class to work with.
class AbstractEvent
{
public:
    virtual void Fill ( Subject *aSubject ) = 0;
};

// A mediator class to do the type casting
template < class TSubject >
class Event : public AbstractEvent
{
public:
    // This is where we do the type cast.
    virtual void Fill ( Subject *aSubject )
    {
        TSubject *iSubject = dynamic_cast<TSubject *>(aSubject);
        // Somehow the compiler knows to call the abstract method below, but if
        // we change its name we'll get an infinite loop - cranky.
       Fill( iSubject );
    }

    // And a new abstract method to be implemented by concrete events.
    virtual void Fill ( TSubject *aSubject ) = 0;
};

// The subject base class
class Subject
{
public:
    // virtual destructor to make this class polymorphic 
    // so we can cast it dynamically.
    virtual ~Subject() { }

    void Subscribe( AbstractEvent *aEvent )
    {
        aEvent->Fill( this );
    }
};

// A concrete subject class.
class ZoomManager : public virtual Subject
{
public:
    int mRatio;
};

// The concrete event
class evZoom : public Event< ZoomManager >
{
public:
    virtual void Fill( ZoomManager *aZoomManager )
    {
        mRatio = aZoomManager->mRatio;
    }

    int mRatio;
};

int main(int argc, const char * argv[])
{
    ZoomManager iZoomManager;
    evZoom      *iEvent = new evZoom();

    iZoomManager.Subscribe( iEvent );

    return 0;
}    
//十二月
班级科目;
//主题类要使用的非模板抽象基类。
类抽象事件
{
公众:
虚拟空白填充(主题*AsObject)=0;
};
//执行类型转换的中介类
模板
类事件:公共抽象事件
{
公众:
//这是我们进行类型转换的地方。
虚拟空白填充(主题*对象)
{
tsObject*IsSubject=动态投影(AsObject);
//不知何故,编译器知道调用下面的抽象方法,但是如果
//我们改变它的名字,我们会得到一个无限循环-古怪。
填充(主体);
}
//一种新的抽象方法,通过具体事件来实现。
虚拟空洞填充(tsObject*AsObject)=0;
};
//主题基类
班级科目
{
公众:
//虚拟析构函数使该类具有多态性
//因此,我们可以动态地强制转换它。
虚拟~Subject(){}
作废订阅(AbstractEvent*aEvent)
{
aEvent->Fill(此);
}
};
//一门具体的学科课。
类ZoomManager:公共虚拟主题
{
公众:
国际货币基金组织;
};
//具体事件
类evZoom:公共事件
{
公众:
虚拟空白填充(ZoomManager*AzoManager)
{
mRatio=azommanager->mRatio;
}
国际货币基金组织;
};
int main(int argc,const char*argv[]
{
ZoomManager iZoomManager;
evZoom*iEvent=新的evZoom();
iZoomManager.Subscribe(iEvent);
返回0;
}    
唯一的问题是,我直觉认为有更好的解决方案;主要是因为我不记得在任何源代码或库中见过像上面这样的中介类,但可能是我的经验不足


有人能为上述问题提供更好的解决方案吗?

是否
ZoomManager
是您在
Fill()
上期望的唯一类型?为什么不更改方法的签名?不-可能有很多具体的主题:ZoomManager、ScrollManager、Composite等。您是否只是尝试切换所有可能的类型?如果是这样,就需要双重分派
dynamic_cast
通常是个坏主意。我不确定你所说的“切换所有可能的类型”到底是什么意思,但有大量的具体主题,因为这是框架的一部分,使用它的应用程序可能会增加数百个——框架本身都不知道。这会排除双重分派吗?我的意思是,在
Fill
上,您似乎每次都希望看到一个
ZoomManager
,或者您有一个开关(每个开关都有一个案例)来决定如何处理其他具体类型。