【问题标题】:C++ Abstraction OOP (Inherit only some method to derived class)C++ 抽象 OOP(仅继承派生类的某些方法)
【发布时间】:2021-08-14 08:03:26
【问题描述】:

假设我有一个套接字类:

class Socket{
public:
    ... Some Code ...
    Socket(int type){
         isServer = type;
        //some code
    }
    virtual void Send(string s);
    virtual void Send(string s, int clientID);
    ... Some Code ...
private:
    int isServer;
};

这既可以用作服务器,也可以用作客户端。

现在我需要 2 个派生类:

class ClientSocket : public Socket{
public:
    ... Some Code ...
};

class ServerSocket : public Socket{
public:
    ... Some Code ...
};

我想要的是 ClientSocket 只能访问 Send(string) 而服务器套接字只能访问 Send(string, int)

我检查了其他一些答案:

这有一个好主意,根本不使用继承,而只是封装(在服务器中有一个套接字实例)。但我想知道这是否可以使用继承来完成。

【问题讨论】:

  • "ClientSocket 只能访问..." 听起来像是编译时属性,但虚函数调用是在运行时调度的。
  • 在我看来,这些 Send 函数不应该是基类 Socket 的一部分,而是应该是继承的类。
  • @Evg 如果你去继承我猜不是编译时间。对于虚拟功能,我必须这样做,因为代码在不同的地方实现以使其独立于平台
  • 设计方面对我来说没有多大意义。服务器和客户端套接字,至少对于 TCP,具有非常不同的行为。服务器套接字根本不应该有任何“发送”或“接收”功能,只有“侦听”和“接受”类型的操作。 “接受”操作返回一个客户端套接字对象,该对象可以发送和接收通用数据。然后你可以有一个类似容器的类,包装多个客户端套接字对象,它可以有一个发送到所有套接字的函数,或者只发送一个特定的套接字。
  • 我要去的地方是如果你必须调用isServer 或者知道你有一个ServerSocket,那么你几乎不会从多态中获得任何好处,所以不要这样做。没有它,程序会更有效率。当您不需要知道确切的派生类型时,多态是最好的。现在你正在对抗Liskov Substituion Principle,这将带来刚刚开始的痛苦。

标签: c++ oop inheritance c++17 abstraction


【解决方案1】:

没有绝对的方法可以做这样的事情。

但这是我的想法:

创建两个类(如接口):

第一类是服务器套接字发送者:

Class ServerSocketSender {
  public:
    virtual void Send(string s, int clientID);
}

第二类是客户端套接字发送者:

Class ClientSocketSender {
  public:
    virtual void Send(string s);
}

由于接口隔离原则,我建议您这样做,将两个发送方法组合在一个类中并在愿望类中启用愿望方法是不明智的选择。

我多次看到的另一个技巧,但我不知道它是否适用于您的情况,称为 SFINAE。通过这个技巧,我认为您可以实现相同的目标,但由于复杂性,我不推荐这种方法。

【讨论】:

  • 我已经告诉过我不想实现任何不同的类,因为那些发送方法使用一些 OS 原生 API,因此使用不同的类会非常令人困惑,因为它会增加代码大小并使其变得困难维持
  • 如果您不想使用额外的类,我建议您将发送方法放在继承类而不是基类中,因为它们具有不同的签名和目的,因此在 OOP 方面是不正确的。
  • 同样不切实际,我也可以直接使用 Socket 类
  • 使用 SFINAE link
  • SFINAE 是一种编译时机制,但虚拟调用是一种运行时机制。
猜你喜欢
  • 1970-01-01
  • 2013-04-18
  • 2017-01-19
  • 2015-01-20
  • 2021-05-14
  • 2018-08-18
  • 2021-06-25
  • 2011-01-05
  • 1970-01-01
相关资源
最近更新 更多