模板类从非模板基类扩展并覆盖函数参数

时间:2018-11-08 15:01:18

标签: c++ c++17

我试图为PacketDecoder创建一个非模板基类,以便可以将Base *存储在std :: map中。解码功能已被正确覆盖。编码函数给我这个错误“编码”不是虚拟的,不能被声明为纯”。我可能会考虑来自Java背景的错误问题。是否有更惯用的c ++方法解决此问题?

class Base {
public:
    virtual Packet* decode(folly::io::Cursor& cursor) = 0;
    virtual void encode(Packet* packet) = 0;
};

template<typename T, typename std::enable_if<std::is_base_of<Packet, T>::value>::type* = nullptr>
class PacketDecoder : public Base {
public:
    virtual T* decode(folly::io::Cursor& cursor) = 0;
    virtual void encode(T *packet) = 0;
};

用法示例:

class TestDecoder : public PacketDecoder<ProxyJoinPacket> {
public:
    ProxyJoinPacket *decode(folly::io::Cursor &cursor) override {
        uint32_t stringLength;
        if (!cursor.tryReadBE<uint32_t>(stringLength)) {
            throw std::runtime_error("Failed to read string length");
        }

        if (cursor.length() < stringLength) {
            throw std::runtime_error("Too few bytes for string");
        }

        auto uuid = cursor.readFixedString(stringLength);
        return new ProxyJoinPacket(uuid);
    }

    void encode(ProxyJoinPacket *packet) override {

    }


};

std::vector<Base*> decoders;
void a() {
    decoders.insert(new TestDecoder()); // error "Allocating an object of abstract class type 'TestDecoder'"
}

1 个答案:

答案 0 :(得分:2)

问题在于您的原始类具有此虚拟功能:

virtual void encode(Packet* packet) = 0;

那么您的继承类具有以下内容:

virtual void encode(T *packet) = 0;

这是两个不同的虚拟函数。

因此,当您这样做时:

void encode(ProxyJoinPacket *packet) override {

您只能覆盖继承的类中的方法,而不能覆盖Base中仍然遗失的方法。

因此,将继承的类更改为使用Packet

virtual void encode(Packet* packet) = 0;

您还可以更改继承的类并添加以下内容:

void encode(Packet* packet) final {
    encode(dynamic_cast<T*> packet);
}

也不要忘记虚拟析构函数...