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++11之後, rule of five)
- move assignment operator (C++11之後, rule of five)
以下為修正過的程式:
#include <iostream> #include <string> class ResourceFreeFix { private: char *m_str; public: ResourceFreeFix() = default; ResourceFreeFix(const char *pstr) : m_str(new char[128]) { std::strcpy(m_str, pstr); } // rule of three ~ResourceFreeFix() { delete [] m_str; } ResourceFreeFix(ResourceFreeFix &Source) : m_str(new char[128]) { strcpy(m_str, Source.m_str); } void operator = (ResourceFreeFix &Source) { m_str = Source.m_str; Source.m_str = nullptr; } }; int main() { ResourceFreeFix c("resource"); { // d will release resource of c ResourceFreeFix d; // FIX: assign c to d d = c; } // c will release resource return 0; }
不過有些人的class並不需要使用copy constructor或copy assignment operator.則可以使用兩種方式來解決
- 把函數定義在private
- 在函數後方加上delete (c++11之後)
留言
張貼留言