【发布时间】:2013-06-05 16:43:33
【问题描述】:
我有以下课程:
class Socket
{
Socket();
Socket( SOCKET s );
};
class Connection : public virtual Socket
{
Connection( IP ip );
};
这两个类包含一些纯虚函数和一些非虚函数以及它们自己的一些数据。它们的重点是我将派生一些套接字类型,实现不同的协议。
所以我专攻这两个课程:
class ProtocolSocket : public virtual Socket
{
ProtocolSocket() {}
ProtocolSocket( SOCKET s ) : Socket( s ) { ; }
};
class ProtocolConnection : public ProtocolSocket, public virtual Connection
{
ProtocolConnection( SOCKET s, IP ip ) : ProtocolSocket( s ), Connection( ip ) {;}
};
出了点问题 - 我相信你们中的许多人都可以看到。我尝试创建一个 ProtocolConnection:
new ProtocolConnection( s, ip );
施工过程如下:
start ctor ProtocolConnection
start ctor Connection
start ctor Socket
Socket(); - default ctor via Connection's init list
end ctor Socket
Connection(); - default ctor ProtocolConnection's init list
end ctor Connection
start ctor ProtocolSocket
start ctor Socket
// Socket( s ); - skipped!!! - would have been from init
// list of ProtocolSocket, but ctor for this object
// already called!
end ctor Socket
ProtocolSocket( s ); -from init list of ProtocolConnection()
end ctor ProtocolSocket
ProtocolConnection( s, ip );
end ctor ProtocolConnection
跳过第二个 Socket 构造函数是语言规范所说的应该发生的事情,并且有充分的理由。
如何让它调用带有 Socket(s) 的构造函数,而不是之前的那个?
我打算拥有多个派生类,例如还有 OtherProtocolSocket 和 OtherProcolConnection,与 ProtocoSocket 和 ProtocolConnection 对象处于同一级别。
我想要达到的效果是我想构造 ProtocolSocket 和 ProtocolConnection 对象,然后将它们作为 Socket 和 Connection 对象传递给我的系统。因此,在我制作了一个实现给定协议的套接字后,我只需对其进行读写,而不用担心底层协议的细节。
Connection 对象需要继承 Socket 对象的所有方法。
@更新:
DyP 建议在 ProtocolConnection 中为 Socket 添加初始化器。这解决了问题。我会给你一个接受...但这只是在评论中。
【问题讨论】:
-
是否可以通过让 Connection 类持有一个 Socket 对象而不是从 Socket 派生来避免使用虚拟继承?从长远来看,通过保持 Socket 和 Connection 的概念彼此独立,这可能会使事情变得更简单。
-
如果我通过遏制来做到这一点,那么我必须通过诸如“读取”和“写入”之类的方法从 Connection 到包含的套接字。另外,当它们已经连接时,我不能互换使用套接字和连接。所以连接和套接字都是读/写的东西。连接对象是我可以称之为“连接”的东西。
-
[class.base.init]/10 "首先,并且仅对于最派生类 (1.8) 的构造函数,虚拟基类按照它们出现在深度优先左侧的顺序进行初始化从右到右遍历基类的有向无环图,其中“从左到右”是派生类基类说明符列表中基类的出现顺序。”让我想知道为什么
Connection在Socket之前初始化(通过ProtocolSocket)。 -
您是否尝试将
Socket的初始化程序放入ProtocolConnection的mem-initializer-list 中? -
@DyP:有效。太棒了。
标签: c++