假设以下代码:
class ChannelHandle;
class SessionHandle;
typedef ChannelHandle& ChannelHandleRef;
typedef SessionHandle& SessionHandleRef;
class RemoteChannelHandle
{
public:
RemoteChannelHandle(
ChannelHandleRef pChannelHandle, SessionHandleRef pSessionHandle);
RemoteChannelHandle(RemoteChannelHandle&&);
~RemoteChannelHandle();
void CloseChannel();
#ifndef _MSC_VER
RemoteChannelHandle& operator=(RemoteChannelHandle&&) = delete;
RemoteChannelHandle(RemoteChannelHandle const&) = delete;
RemoteChannelHandle& operator=(RemoteChannelHandle const&) = delete;
#endif
private:
LIBSSH2_CHANNEL* channel;
ChannelHandleRef channelHandle;
SessionHandleRef sessionHandle;
};
RemoteChannelHandle::RemoteChannelHandle(
ChannelHandleRef pChannelHandle, SessionHandleRef pSessionHandle)
: channel(nullptr), channelHandle(pChannelHandle), sessionHandle(pSessionHandle)
{
// OPEN SSH CHANNEL
}
RemoteChannelHandle::~RemoteChannelHandle()
{
try
{
CloseChannel();
}
catch (...)
{ }
}
void RemoteChannelHandle::CloseChannel()
{
if (channel == nullptr)
{
return;
}
// CLOSE SSH CHANNEL. THROW IF SOMETHING GOES WRONG
channel = nullptr;
}
~RemoteChannelHandle()
,但第二次将在
ChannelHandle的dtor;因此,数据成员channelHandle
我们需要将channel
注入其中。这个参考可能是
通过执行~RemoteChannelHandle()
。sessionHandle
包含打开SSH所需的LIBSSH2_SESSION*
渠道。因为我不想传递LIBSSH2_SESSION*
,所以
参考不能消除。当我为RemoteChannelHandle定义move ctor时会出现问题。我需要清除“移动”实例的成员。但是,没有办法清除参考。那么,在这做什么?
(const) std::shared_ptr
代替参考?我甚至可以使用
裸指针,因为没有涉及所有权。我意识到有一些争论
关于使用引用作为数据成员,但除了
移动ctor,我预见没有其他情况我需要重新安装
句柄(这就是我首先使用引用的原因)。channel != nullptr
为此目的)?我已经找到了替代方案,并没有找到明确的答案。当然,这可能意味着没有明确的答案。
感谢您的时间。
编辑(回复Mankarse): ChannelHandle仅用于执行清理步骤2。这是一个简化的定义:
class ChannelHandle
{
public:
ChannelHandle();
ChannelHandle(ChannelHandle&&);
~ChannelHandle();
#ifndef _MSC_VER
ChannelHandle& operator=(ChannelHandle&&) = delete;
ChannelHandle(ChannelHandle const&) = delete;
ChannelHandle& operator=(ChannelHandle const&) = delete;
#endif
LIBSSH2_CHANNEL* GetChannel() { return channel; }
void SetChannel(LIBSSH2_CHANNEL* pChannel) { channel = pChannel; }
void FreeChannel();
private:
LIBSSH2_CHANNEL* channel;
};
SessionHandle是LIBSSH2_SESSION*
的RAII封装。它在ctor上调用libssh2_session_init()
,在dtor调用libssh2_session_free()
。其他类似的类负责SSH会话的init / cleanup的其他步骤,但这是我们从libssh2获取LIBSSH2_SESSION*
的地方,而SessionHandle拥有它。再一次,简化定义:
class SessionHandle
{
public:
SessionHandle();
SessionHandle(SessionHandle&&);
~SessionHandle();
void CloseSession();
LIBSSH2_SESSION* GetSession() { return session; }
#ifndef _MSC_VER
SessionHandle& operator=(SessionHandle&&) = delete;
SessionHandle(SessionHandle const&) = delete;
SessionHandle& operator=(SessionHandle const&) = delete;
#endif
private:
LIBSSH2_SESSION *session;
};
答案 0 :(得分:3)
你自己回答了这个问题:
我甚至可以使用裸指针,因为没有涉及所有权。