我正在使用一个实现不同类型网络协议(protocol)的库,就像下面的简化示例一样,它有望说明我遇到的问题。注意:这都是伪代码,只是为了显示整个问题。
class Network
{
virtual void connect() {...}
void readPacket() = 0;
};
class NetworkClient : public Network
{
virtual void connect(int ip, int port) {super::connect() ...}
};
class NetworkServer : public Network
{
virtual void connect(int port) {super::connect() ...}
};
class ProtocolAClient : public NetworkClient
{
void readPacket() {...}
};
class ProtocolAServer : public NetworkServer
{
void readPacket() {...}
};
class ProtocolBClient : public NetworkClient
{
void readPacket() {...}
};
class ProtocolBServer : public NetworkServer
{
void readPacket() {...}
};
现在在我的应用程序中,我想要一个客户端和一个服务器,它们应该是 ProtocolA 或 ProtocolB 客户端/服务器,具体取决于用户选择连接的协议(protocol)。
所以我想我可以像这样创建我的应用程序类。
class AppClient : public NetworkClient
{
... custom functionality needed by the app client ...
void sendAppData(...)
};
class AppServer : public NetworkServer
{
... custom functionality needed by the app server ...
void sendAppData(...)
};
然后我想到,当我需要一个客户端时,例如,在应用程序中,我可以这样做。
AppClient *client;
if(useProtocalA)
client = new ProtocolAClient;
else
client = new ProtocolBClient;
client->sendAppData();
但是编译器很快让我知道这是不可能的,因为 ProtocolAClient 和 ProtocolBClient 不是 AppClient。这是确切的编译器错误。
error C2440: '=' : cannot convert from 'ProtocolAClient *' to 'AppClient *'
所以我的下一个想法是制作 AppClient 和 AppServer 模板类,但这也行不通,因为您无法获得指向实例的指针,因为指针没有这样的模板参数。
AppClient *client; <--- Uh oh... missing template argument!
if(useProtocalA)
client = new AppClient<ProtocolAClient>;
else
client = new AppClient<ProtocolBClient>;
client->sendAppData();
这看起来应该是一个很简单的问题来解决,但我似乎看不到解决方案。
最佳答案
所以你有以下类:
class Network
{
virtual void connect() {...}
void readPacket() = 0;
}
class NetworkClient : public Network
{
virtual void connect(int ip, int port) {super::connect() ...}
}
class AppClient : public NetworkClient
{
... custom functionality needed by the app client ...
void sendAppData(...)
}
class ProtocolAClient : public NetworkClient
{
void readPacket() {...}
}
class ProtocolBClient : public NetworkClient
{
void readPacket() {...}
}
问题是你想要一个 AppClient
对象,但是 ProtocolAClient
类型为 NetworkClient
而不是输入 AppClient
.
你的继承看起来像这样:
Network ---- NetworkClient ---- ProtocolAClient
|---- ProtocolBClient
|---- AppClient
如您所见,ProtocolAClient
都不是也不ProtocolBClient
类型为 AppClient
, 但它们都是 NetworkClient
类型.
所以,如果你想让这段代码工作:
AppClient *client;
if(useProtocalA)
client = new ProtocolAClient;
else
client = new ProtocolBClient;
client->sendAppData();
您必须进行以下更改之一:
A) 改变你的 ProtocolAClient
和 ProtocolBClient
继承AppClient
类:
class ProtocolAClient : public AppClient
{
void readPacket() {...}
}
class ProtocolBClient : public AppClient
{
void readPacket() {...}
}
现在你的继承看起来像这样:
Network ---- NetworkClient ---- AppClient ---- ProtocolAClient
|---- ProtocolBClient
或 B) - 建议:不要使用 AppClient,因为您已经拥有 NetworkClient:
NetworkClient*client;
if(useProtocalA)
client = new ProtocolAClient;
else
client = new ProtocolBClient;
client->sendAppData();
关于C++从多个选择中实例化子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28161419/