在C ++类中包装Winsock函数

时间:2012-07-01 14:13:02

标签: c++ oop winsock2

我看到有些人创建了一个“is-a”关系,如下所示:

class TCPClient : public Socket
{
public:
    TCPClient(const std::string& host, unsigned short port);
};

其中Socket类实现Winsock函数,如Connect(),Close(),Bind()等。

实施例

但是对于我来说,这对套接字编程的新手来说并不自然。

上述层次结构是否比下面的“has-a”对应物更具逻辑意义?

class TCPClient
{
public:
    TCPClient(const std::string& host, unsigned short port);
    ....
private:
    Socket m_socket;
};

4 个答案:

答案 0 :(得分:3)

TCPClient使用套接字或具有套接字,但它本身不是套接字,并且通常不希望能够在预期的套接字的任何地方替换TCPClient。因此,公共继承没有意义。

可以在这种情况下使用私有继承,但(至少在典型情况下)它可能也没有多大意义。当基类提供至少一个您计划在子类中重写的虚函数时,私有继承才有意义。如果你有一个虚函数并需要覆盖它,你就没有真正的选择,只能使用继承。我不希望Socket类有虚函数;这通常不适用于此。

这基本上会导致你的第二个解决方案:TCPClient应该包含一个Socket实例,而不是使用继承。

但是,我应该补充一点,你所展示的Socket类似乎将实际套接字的概念与地址的概念混为一谈。我的第一个套接字类(之前)就是这样工作的,但从那时起我就得出结论,它并不是一个理想的设计。我已经确信将地址的概念与套接字本身分开是值得的。虽然我的内容不那么复杂,但我觉得有趣的是,我提出的内容几乎就像它可能是Boost ASIO派生的原型。它更小更简单,但无论如何,很多基本想法都非常相似。

这导致了我的下一个建议:看看Boost ASIO。缺乏一个相当具体的理由,这是我在大多数新代码中建议(并且通常使用)的东西。虽然(正如我上面所说)我多年来编写了几个套接字类,但是我已经在很长一段时间内没有使用它们中的任何一个(任何?)新代码 - 它们实际上只比ASIO有两个可能的优势。第一个只适用于我:因为我在ASIO存在之前编写和使用它们,我已经理解它们以及它们是如何工作的。第二个可能是相似的:至少对我来说,它们看起来更小更简单(但是,这可能只是因为我先使用它们)。即便如此,(例如)使用其他人已经理解的东西的优点也很容易胜过。

答案 1 :(得分:1)

使用has-a。 TCPClient使用类似于使用电话的人的套接字。你会从电话中找到一个人吗?

答案 2 :(得分:0)

class TCPClient : public Socket
{
public:
    TCPClient(const std::string& host, unsigned short port);
};

网络套接字不仅用于TCP / IP,如果您计划重用“Socket”类以使用网络套接字实现其他协议,则上述设计更合适。例如:

class UDPClient : public Socket
{
};

答案 3 :(得分:0)

我会这么说。 Socket是一个抽象,一个文件描述符(UNIX)或句柄(Windows),它有与之关联的资源并由操作系统管理。如果我们考虑OSI模型,套接字很适合表示层(它呈现或描述两个节点之间的通信通道),而使用套接字的程序则位于应用层。

考虑到这一点,我宁愿不继承套接字,除非我实现一种高级套接字(通过类比:C指针与智能指针)来呈现和处理逻辑连接,并以某种方式管理与之相关的资源插座。如果XYZClient是一个应用程序,其目标是实现一些业务或数据处理逻辑,我不会将这两个概念混合在一起并使用第二种方法(has-a)。

我会拆分基础架构/特定于资源和业务/应用程序的逻辑。