考虑以下类:
class SessionConnection
{
...
private:
SessionHandle sessionHandle;
RemoteSessionHandle remoteSessionHandle;
};
它的 ctor 是这样的:
SessionConnection::SessionConnection(whatever) :
..., sessionHandle{some_more_whatever}, remoteSessionHandle{sessionHandle}, ...
{
...
}
RemoteSessionHandle
看起来像这样:
class RemoteSessionHandle
{
...
private:
SessionHandle* sessionHandle;
};
RemoteSessionHandle::RemoteSessionHandle(SessionHandle const& pSessionHandle) :
..., sessionHandle{&pSessionHandle}
{
...
}
注意:这些类有更多的成员,但我试图坚持这一点。
在构造时,SessionConnection
注入sessionHandle
到remoteSessionHandle
中,它保留一个指向它的指针。
但是,我对移动构造函数有疑问。在搬家之前,我有这个:
movedFromSessionConnection movedToSessionConnection
+------------------------------+ +----------------------------+
| movedFromSessionHandle | | movedToSessionHandle |
| ^ | | ^ |
| | | | | |
| movedFromRemoteSessionHandle | | movedToRemoteSessionHandle |
+------------------------------+ +----------------------------+
每个 RemoteSessionHandle 都指向它的 SessionHandle。搬家后,我得到了这个:
movedFromSessionConnection --- mv ---> movedToSessionConnection
+------------------------------+ +----------------------------+
| movedFromSessionHandle ---- mv ----> movedToSessionHandle |
| ^ -----------------------------------+ |
| | |
| movedFromRemoteSessionHandle - mv -> movedToRemoteSessionHandle |
+------------------------------+ +----------------------------+
的内容movedFromRemoteSessionHandle
已移至movedToRemoteSessionHandle
,因此它现在指向movedFromSessionHandle
。移动到 后处于未知状态movedToSessionHandle
。
我考虑了以下解决方案:
- 从 RemoteSessionHandle 的移动 ctor 中排除指针。我觉得这有点“臭”,因为我还没有找到一个不移动或不作用于所有数据成员的移动 ctor 的示例。
- 从 SessionConnection 中移除 SessionHandle,并改为使其成为 RemoteSessionHandle 的成员。
- 在 RemoteSessionHandle 中实现“常规”移动 ctor(“常规”意味着移动所有数据成员),并让 SessionConnection 的移动 ctor 重新定位 RemoteSessionHandle 中的指针。
在这种情况下,选项 2 和 3 是可能的,因为这些类在设计上是强耦合的。但是,然后我考虑了如果不是这种情况我该怎么办。
我浏览了整个网络,发现没有其他人有这个问题,所以我的第一直觉是相信我忽略了一些非常明显的东西(或者我缺乏这个特定搜索的 google-fu)。
我忽略了任何明显的东西吗?这是一个没有问题的问题,很容易被我忽略的任何东西解决吗?
编辑:
在 Igor 的评论之后,我决定添加更多上下文。我正在使用这些类使用 boost.asio 创建一个 libssh2 会话。libssh2 会话的创建经历了几个状态,并且设置和关闭足够对称,我可以使用 RAII 来管理它(我在此处详细说明)。
RemoteSessionHandle 需要 SessionHandle 是因为后者拥有LIBSSH2_SESSION*
前者操作所需的东西,因此存在依赖关系。