C++从多个选择中实例化子类

标签 c++

我正在使用一个实现不同类型网络协议(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) 改变你的 ProtocolAClientProtocolBClient继承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/

相关文章:

c++ - 在 C++ 中创建缓冲区的问题

c++ - 从 C++ 中的 vector 继承类调用 super 运算符==

c++ - Qt,在构造函数之外修改小部件属性的问题

c++ - 查找重叠 1 位的计数

c++ - boost::locale::date_time 的陷阱

c++ - 将 boost spirit 用于基于堆栈的语言

c++ - 将函数模板转换为模板仿函数

c++ - != 运算符应该在类层次结构中的什么地方定义?

c++ - 随机数发生器 : Should it be used as a singleton?

c++ - push_back() 中的段错误