1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
/** 进程间下载 */ class DLUTILS_EXPORT IpcDownloadClient { public: /** 默认构造函数 */ IpcDownloadClient(); /** 默认析构函数 */ ~IpcDownloadClient(); public: /** 连接服务器 */ bool Connect(uint16_t port); /** 是否已经连接 */ bool IsConnected(); /** 与服务器断开连接 */ void Stop(); /** 获取指定id的游戏的任务状态 */ IpcTaskStatus GetGameStatus(IpcTaskStatusInfo info); /** 启动下载任务或者安装任务 */ uint32_t StartTask(IpcStartTaskInfo info); /** 暂停下载或安装任务 */ bool PauseTask(uint32_t gameId); /** 删除任务 */ bool CancelTask(uint32_t gameId); /** 获取已安装游戏信息 */ IpcGameInstallInfo GetIpcGameInfo(uint32_t gameId); /** 为已完成安装的游戏创建快捷方式 */ IpcShotcutInfo CreateShotcut(uint32_t gameId); private: /** 实现对象 */ class TImpl; TImpl *m_impl; }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
//IpcDownloadClient class implementation class IpcDownloadClient::TImpl { public: TImpl() { } SharedPtr<IpcClient> m_pManagerRpcClient; }; IpcDownloadClient::IpcDownloadClient() { m_impl = new TImpl; } IpcDownloadClient::~IpcDownloadClient() { delete m_impl; } bool IpcDownloadClient::Connect(uint16_t port) { try { assert(m_impl); m_impl->m_pManagerRpcClient.reset(new IpcClient); m_impl->m_pManagerRpcClient->Connect(port); return true; } catch (std::exception& e) { (void)(e); #ifdef _DEBUG OutputDebugStringA(e.what()); #endif // _DEBUG return false; } } bool IpcDownloadClient::PauseTask(uint32_t gameId) { if (!m_impl ||!m_impl->m_pManagerRpcClient || !IsConnected()) { return false; } try { return IpcDownloadStub::PauseTask(m_impl->m_pManagerRpcClient.get(), gameId); } catch(const std::exception &e) { (void)(e); #ifdef _DEBUG OutputDebugStringA(e.what()); #endif // _DEBUG } return false; } uint32_t IpcDownloadClient::StartTask(IpcStartTaskInfo info) { IpcStartTaskStatus status = IPC_TASK_STATUS_FAILED; if (!m_impl ||!m_impl->m_pManagerRpcClient || !IsConnected()) { return status; } try { return IpcDownloadStub::StartTask(m_impl->m_pManagerRpcClient.get(), info); } catch(const std::exception &e) { (void)(e); #ifdef _DEBUG OutputDebugStringA(e.what()); #endif // _DEBUG } return status; } bool IpcDownloadClient::CancelTask(uint32_t gameId) { if (!m_impl ||!m_impl->m_pManagerRpcClient || !IsConnected()) { return false; } try { return IpcDownloadStub::CancelTask(m_impl->m_pManagerRpcClient.get(), gameId); } catch(const std::exception &e) { (void)(e); #ifdef _DEBUG OutputDebugStringA(e.what()); #endif // _DEBUG } return false; } IpcTaskStatus IpcDownloadClient::GetGameStatus(IpcTaskStatusInfo info) { if (!m_impl ||!m_impl->m_pManagerRpcClient || !IsConnected()) { return IpcTaskStatus(); } try { return IpcDownloadStub::GetIpcTaskStatus(m_impl->m_pManagerRpcClient.get(), info); } catch(const std::exception &e) { (void)(e); #ifdef _DEBUG OutputDebugStringA(e.what()); #endif // _DEBUG } return IpcTaskStatus(); } IpcGameInstallInfo IpcDownloadClient::GetIpcGameInfo(uint32_t gameId) { if (!m_impl ||!m_impl->m_pManagerRpcClient || !IsConnected()) { return IpcGameInstallInfo(); } try { return IpcDownloadStub::GetIpcGameInfo(m_impl->m_pManagerRpcClient.get(), gameId); } catch(const std::exception &e) { (void)(e); #ifdef _DEBUG OutputDebugStringA(e.what()); #endif // _DEBUG } return IpcGameInstallInfo(); } IpcShotcutInfo IpcDownloadClient::CreateShotcut(uint32_t gameId) { if (!m_impl ||!m_impl->m_pManagerRpcClient || !IsConnected()) { return IpcShotcutInfo(); } try { return IpcDownloadStub::CreateShotcut(m_impl->m_pManagerRpcClient.get(), gameId); } catch(const std::exception &e) { (void)(e); #ifdef _DEBUG OutputDebugStringA(e.what()); #endif // _DEBUG } return IpcShotcutInfo(); } void IpcDownloadClient::Stop() { if (!m_impl ||!m_impl->m_pManagerRpcClient || !IsConnected()) { return ; } m_impl->m_pManagerRpcClient.reset(); } bool IpcDownloadClient::IsConnected() { if (!m_impl || !m_impl->m_pManagerRpcClient) { return false; } return m_impl->m_pManagerRpcClient->IsConnected(); } |
class TImpl;在类的头文件中进行定义,这样的做法我认为是
(1)“编译包含过多不必要的头文件”,这些头文件是实现时候使用的,没有必要包含在头文件中,如果别人使用你的类,那么他就需要将哪些和他无关的头文件也包含进来,违反了“强内聚”原则;特别是作为“基础库”使用的时候
(2)将一个类分成两个来使用,这样便有了层次,如果是简单的类,则第二层是对第一层简单的包装,隐藏了头文件而已,接口什么的都是抄过来的,主类无需附带任何私有数据和方法,仅仅作为一个壳子,Timpl类作为实体。若是复杂的类,则Timpl类复杂核心功能,主类负责协调功能,主类有自己的私有数据和方法,Timpl类有自己的方法和数据,并不是抄主类的接口,他们分工明确。
何时使用:
(1)主类头文件中头文件过多,需要隐藏实现细节
(2)主类比较复杂,分成两个类实现太牛刀,一个类太乱,可以使用Timpl分层,两者各有分工,可以隐藏一部分头文件,可以让层次清晰。
总结:
我觉得只有在主类头文件中“不必要的头文件”过多的时候才需要使用,而其他方面完全无需使用,若需要分层则应该调理清晰,分成多个类文件,不要I放在一起,混在一个CPP文件中很乱,而且意义不大,不如再分几个底层类来使用,即使底层类只有一个方法或接口,后期维护完全清晰明朗。