【发布时间】:2021-09-12 18:50:47
【问题描述】:
我有 2 个接口:Socket 和 ListeningSocket,以及 2 个类:BerkeleySocket 和 BerkeleyListeningSocket,它们实现了这些接口。
会有更多的socket类型,现在只是一个例子。
问题是BerkeleyListeningSocket 继承了BerkeleySocket 和ListeingSocket。它继承BerkeleySocket 以避免应对基本套接字方法实现,并继承ListeningSocket 来实现侦听套接字方法。
但是类BerkeleySocket和接口ListeningSocket都继承了接口Socket,但是ListeningSocket不像BerkeleySocket那样没有实现它的纯虚方法(在例子中是Close方法),所以我不能创建一个对象BerkeleyListeningSocket 因为错误 unimplemented pure virtual method 'Close'。
说明问题的示例代码:
// This is an example code, so there will be more methods.
// ----------------
// Interfaces
// ----------------
class Socket
{
public:
virtual ~Socket() = default;
virtual void Close() = 0;
};
class ListeningSocket : public Socket
{
public:
virtual bool Listen(int max_connections) = 0;
};
// ----------------
// Implementations
// ----------------
// Implementation of base socket.
class BerkeleySocket : public Socket
{
public:
explicit BerkeleySocket(SOCKET s) : socket_(s) {}
~BerkeleySocket() override { closesocket(this->socket_); }
void Close() override { closesocket(this->socket_); }
protected:
const SOCKET socket_;
};
// Listening socket implementation.
// Inherits BerkeleySocket to avoid coping code of implementation of base socket methods, such as Close.
// There will be more derivatives of BerkeleySocket, so I can't move Close method to BerkeleyListeningSocket.
// Implements ListeningSocket interface. But there is a problem.
// Both BerkeleySocket and ListeningSocket inherits Socket interface,
// so ListeningSocket have unimplemented method Close
// and I can't create an object of BerkeleyListeningSocket because of it.
class BerkeleyListeningSocket : public BerkeleySocket, public ListeningSocket
{
public:
explicit BerkeleyListeningSocket(SOCKET s) : BerkeleySocket(s) {}
bool Listen(int max_connections) override { return listen(this->socket_, max_connections) != SOCKET_ERROR; }
};
int main() {
// Error! Unimplemented pure virtual method Close.
BerkeleyListeningSocket listening_socket(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
return 0;
}
希望得到您的帮助! 提前致谢!
【问题讨论】:
-
它继承了 BerkeleySocket 以避免应对基本套接字方法实现 → 这是您设计中的错误。它应该实现接口,但使用实现(作为数据成员)。 — 好吧,错误可能有点大,有充分的理由像你那样做,只是它不一定是你应该做的第一件事。
-
ListeningSocket不会覆盖Close(),因此Close()在BerkeleyListeningSocket中仍然是纯虚拟的。显而易见的解决方法是在BerkeleyListeningSocket中覆盖Close(),并在覆盖中调用BerkeleySocket::Close()。或者,也许,使Socket成为BerkeleySocket和ListeningSocket的虚拟基础。从这个问题中不清楚这是否合适。 -
我不会继承
Socket中的ListeningSocket。事实上,我会将这些接口重命名为:ClosableListener。国际海事组织你把很多东西放在一个班级里。
标签: c++ oop inheritance interface