这是多态的适当使用吗?

10

考虑以下语法上正确的(?)伪代码:

class Event {
public:
    virtual int getID() const = 0;
    virtual int getSize() = 0;
    virtual void* getData() = 0;
    virtual void setData() = 0;
    //(I cannot define data at this level 'cos I don't know what it is yet)
}

class SpecialEvent : class Event {
public:
    virtual int getPGNID() const = 0;
    int getSourceAddress() {return source_address;}
    int setSourceAddress(int source_address) {this->source_address = source_address;}
protected:
    int source_address;
}

template <typename T, typename E>
class EventWrapper : public E {
    T data;
public:
    static int EVENT_ID;
    //implements everything in Event...EVENT_ID is assigned at runtime by some registry
}

class AnEvent : public EventWrapper<int, Event> {
     //public methods specific to AnEvent...
}

class AnotherEvent : public EventWrapper<long, SpecialEvent> {
    int getPGNID() const {static int ID = 10; return ID;}
}

class TheProcessingClass {
    AnEvent event1;
    AnotherEvent event2;

    void process(Event& e);
    void process(SpecialEvent& e);

    void doSomething() {
        process(event1);  //should invoke process(Event&)
        process(event2);  //should invoke process(SpecialEvent&)
    }
}

基本上,我有一个包装类,它包装了类型为T的数据,并继承自某种类型的E(在这种情况下是Event或SpecialEvent)...
起初,我打算创建两个包装类EventWrapper和SpecialEventWrapper,直到我发现两个类中都会有完全相同的代码(只要它扩展自某种类型的Event)
首先,这听起来像是一种基于策略的设计。然而,Events没有任何特殊的行为...它们只是保存一些数据...我是否滥用了这种模式?
其次,有没有更好的方法来做到这一点?我在这里过于简化了事情,但任何见解将不胜感激...
编辑 我更新了我的示例...简而言之,处理类正在监听事件,并应根据事件采取行动。希望这有所帮助...

+1 表示“语法正确的伪代码” =) - fouronnes
3个回答

1
我建议将process()作为事件类的成员函数添加进去。
class Event {
    int getID() const;
    void process();
    //class stuff
}

class SpecialEvent : class Event {
    int getSpecialID() const;
    void process(); //special version of process()
    //class stuff
}


class TheProcessingClass {
    Event event1;
    SpecialEvent event2;

    void doSomething() {
        event1.process();
        event2.process();
    }
}

@T Reddy:那又怎样?如果你不需要它成为POD,就将其作为成员函数。 - Puppy

0

我已经玩了一会儿你的代码。 在我看来,你正在尝试做类似于boost::any的事情。

如果不是这样,我的主要建议是为Event和SpecialEvent使用真正的抽象接口。你现有的设计只有部分多态性,因为SpecialEvent有一个方法,更重要的是一个IDENTITY方法,它没有覆盖Event::getId。那感觉很糟糕,我相信当你以任何通用方式依赖Id概念时,这肯定会导致你遇到困难。

在你的设计中,你需要建立一个清晰的类(类型)身份和对象(实例)身份之间的区别。到目前为止,你似乎只处理对象(实例)身份,否则你的id()方法将是静态的。 RTTI可以用于建立类身份,但依赖于实际派生类型是一个经典的反模式,通常表示破碎的多态性。我从未需要过RTTI,甚至不是为了记录目的。


0

回答你的问题的关键代码是两个处理函数及其功能。如果将派生自SpecialEvent的SpecialEvent或EventWrapper传递给process(Event&)函数,这样做是否不正确?如果是这样,那么这不是多态性的适当使用。


我认为将SpecialEvent传递给仅处理Events的内容并不是不正确的...无论谁在监听Events,可能都不关心它是SpecialEvent类型... - Tim Reddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接