【发布时间】:2015-11-04 14:26:46
【问题描述】:
我在实现一个在另外两个类的抽象类中声明的虚函数时遇到了麻烦,在不同的头文件中。
当我在类 ProtocolLogin 中实现已经在 ProtocolGame 中实现的虚函数“parsePacket”时,编译器返回“函数已经有一个主体”。
Error 1 error LNK2005: "private: virtual void __cdecl ProtocolGame::parsePacket(class NetworkMessage &)" (?parsePacket@ProtocolGame@@EEAAXAEAVNetworkMessage@@@Z) already defined in protocolgame.obj
Error 2 error LNK2001: unresolved external symbol "public: virtual void __cdecl ProtocolLogin::parsePacket(class NetworkMessage &)" (?parsePacket@ProtocolLogin@@UEAAXAEAVNetworkMessage@@@Z)
然后我尝试创建一个名为 parseWater 的新虚拟函数,它将仅在 Class ProtocolLogin 中实现,编译器返回“函数需要在 ProtocolGame 声明”,但如果我这样做,我会再次得到:“函数已经有了身体”。所以,我只是不再关注了。请帮助我理解:)
它就像一个无限循环。
class Protocol (Header File 1)
{
public:
explicit Protocol(Connection_ptr connection) : m_connection(connection)
virtual ~Protocol() = default;
// non-copyable
Protocol(const Protocol&) = delete;
Protocol& operator=(const Protocol&) = delete;
virtual void parsePacket(NetworkMessage&) {}
void onRecvMessage(NetworkMessage& msg); // Function that calls parsePacket
virtual void onRecvFirstMessage(NetworkMessage& msg) = 0;
class ProtocolGame final : public Protocol (Header File 2)
{
public:
// static protocol information
enum {server_sends_first = true};
enum {protocol_identifier = 0}; // Not required as we send first
enum {use_checksum = true};
static const char* protocol_name() {
return "gameworld protocol";
}
explicit ProtocolGame(Connection_ptr connection);
private:
void parsePacket(NetworkMessage& msg) final; //implementation //Works
void onRecvFirstMessage(NetworkMessage& msg) final; //implementation //Works
class ProtocolLogin final : public Protocol (Header File 3)
{
public:
// static protocol information
enum {server_sends_first = false};
enum {protocol_identifier = 0x01};
enum {use_checksum = true};
static const char* protocol_name() {
return "login protocol";
}
explicit ProtocolLogin(Connection_ptr connection) : Protocol(connection) {}
void onRecvFirstMessage(NetworkMessage& msg); //work
void parsePacket(NetworkMessage& msg); // dont work
【问题讨论】:
-
不清楚真正的代码是什么,真正的错误是什么。请按原样提供代码,并按报告错误的行放置错误。顺便说一句,在代码中添加 final 的目的是什么?我相信,这是一种不好的做法。
-
一方面,
void onRecvLiquid();不是虚拟的 -
MCVE.
-
parseAlcohol()也不是,所以你把它指定为 final 是不正确的。 -
我已经编辑并更改了我在这里引用时拼错的功能。对不起。现在是正确的。请大家复习一下:)