我正在使用一个实现不同类型网络协议的库,如下面的简化示例所示,希望可以说明我遇到的问题。注意:这都是伪代码,只是为了显示整体问题。
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客户端/服务器,这取决于用户选择连接哪个协议。
所以我想我可以创建这样的应用程序类。
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++ - C++从多个选择实例化子类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28161419/