發表文章

目前顯示的是 10月, 2017的文章

rule of three

rule of three or rule of five (額外多move). 此rule是根據rules of thumb in C++所產生 主要是為了預防再做資源管理時發生不可預期的錯誤, 所建議的撰寫規則. 如下為一個經由給定(=)後所產生的double free問題. #include <iostream> #include <string> class ResourceFreeFailed { private: char * m_str; public: ~ ResourceFreeFailed() { delete [] m_str; } ResourceFreeFailed() = default ; ResourceFreeFailed( const char * pstr) : m_str( new char [ 128 ]) { std :: strcpy(m_str, pstr); } }; int main () { ResourceFreeFailed c( "resource" ); { // d will release resource of c ResourceFreeFailed d; // ERROR: assign c to d d = c; } // c will release resource, but someting is wrong return 0 ; } [1][2]定義了兩種情況,在撰寫class時候需要記得此規則: 撰寫的class有需要自己做資源管理(resource management) 當撰寫以下其中一個成員函數時,需要一併明確定義其他成員函數 destructor copy constructor copy assignment operator move constructor (C+...

Pointer to Implementor(PIMPL)

概念 最近看到PIMPL的設計, 基於好奇就看了網路上的資訊. PIMPL主要的概念根據[1][2][3]可以分為兩點 (1)進一步的隱藏私有部分的成員變數及函數. 可以把所需的變數通通包在class Impl 裡面. (2)對於程式需要新增/刪除成員變數的時候,由於已改成Impl的方式.可以減少自己程式重新編譯的時間以及避免影響使用這些函式庫的程式因為ABI關係也重新編譯. 程式範例 work.hpp為一個外層handle的class. 主要是透過public的函數作為一個介面來呼叫實作在Impl的Class程式. line8~9是使用forward declaration.[4][5][6].所以必須使用pointer或reference的方式宣告Impl work.hpp 1 class Handle 2 { 3 public : 4 Handle(); 5 void CallA (); 6 7 private : 8 class Impl ; 9 Impl * m_Impl; 10 }; Line 4~8為Impl類別的實作. line 17則是handle類別透過CallA介面去呼叫實際實行的部分. work.cpp 1 #include < iostream > 2 #include "work.hpp" 3 4 class Handle :: Impl 5 { 6 public : 7 void DoA() { std :: cout << "Do A\n"; } 8 }; 9 10 Handle :: Handle() 11 { 12 m_Impl = new Impl; 13 } 14 15 void Handle :: CallA() 16 { 17 m_Impl -> DoA(); 18 } 19 20 int main() 21 ...