首页 > 解决方案 > 从父类的相同方法调用派生类方法

问题描述

我的问题如下:我正在编写服务器和客户端之间的可扩展通信协议。需要传输的对象使用命令设计模式

这是课堂格式:

class command {

  public:
    using id = uint8_t;
    using buffer = std::vector<char>;

    enum command_t: id {a_command, another_command};

    command() = delete;
    command(id id): id_(id) {}

    static command* unserialize(buffer);
    virtual buffer const serialize() const = 0;

    virtual void execute() = 0;

  protected:
    /* Not possible, see further where I explain. Keeping it here for
       my example */
    virtual static command* do_unserialize(buffer::iterator, buffer::iterator) = 0;
    id id_;

};

class a_command;
class another_command;

每个命令都将是command. id将command_t与每个命令相关联。在上面的示例中,a_command并且another_command也将具有相应的类。

command::serialize在派生类中实现。它所做的是将类的所有需要​​的信息写入字节数组并返回。当然,受保护的情况也是如此command::do_unserialize——它需要一个字节数组并将其转换为正确类型的命令。但问题是:

缓冲区的第一个字节总是command::id好的子类相关联。当服务器/客户端接收数据时,它将读取命令 ID,然后需要能够将其反序列化为正确的命令类型。这就是为什么它需要调用静态函数command::unserialize而不是子类之一的原因do_unserialize


一个快速而肮脏的修复将是command::unserialize这样的:

command* command::unserialize(buffer b) {

    auto it{b.begin()};

    command::id const id{*it++};

    switch(static_cast<command::command_t>(id)) {
        case command::command_t::a_command:
            return a_command::do_unserialize(it, b.end());
        case command::command_t::another_command:
            return another_command::do_unserialize(it, b.end());
        default: 
            throw std::invalid_argument("command::unserialize: unknown command ID");
    }   
}

*** 实际上甚至没有,你不能有一个虚拟的静态成员函数。所以我不知道它是如何实现的。

即使它有效,它也不是很有趣,因为它意味着必须为每个创建的新命令复制一行代码。

编辑:一个工作示例是移动do_unserialize到子类构造函数并返回指向新创建对象的指针。

class derived_command: public command {
  public:
    derived_command(buffer::iterator beg, buffer::iterator end) {
        // do_unserialize logic
    }
};

// unserialize
switch (id) {
    case command::command_t::derived_class: return new derived_class(b.begin(), b.end());
}
// ...

因此,我的问题是这样的:有没有办法只从command::id现场动态链接新命令?一种从其 ID 推断要使用的子类的方法?否则,我的设计有缺陷吗?有没有更好的方法来做我想做的事情?

谢谢!

标签: c++objectnetworkingpolymorphismderived-class

解决方案


推荐阅读