最近實現了一個string類,添加了一些c++11元素。
除了基本的構造析構函數,拷貝構造和賦值函數,另外添加移動拷貝和賦值函數。default是一個很方便的特性有木有。
//default constructor KianString()=default; KianString(const char *c): ch_(0) { ch_ = (char*)malloc(sizeof(char)*(strlen(c)+1)); strncpy(ch_, c, strlen(c)+1); }; ~KianString(){ free(ch_); } //copy constructor KianString(const KianString &str){ ch_ = (char*)malloc(sizeof(char)*(str.size()+1)); strncpy(ch_, str.ch_, str.size()+1); } //assign operator, is ok for both lvalue and rvalue! KianString &operator=(KianString str) noexcept { swap(*this, str); return *this; } //move constructor KianString(KianString &&str) noexcept : ch_(str.ch_) { str.ch_ = NULL; }
賦值拷貝采用了copy and swap idiom:
inline void swap(KianString &str1, KianString &str2){ using std::swap; swap(str1.ch, str2.ch); } //assign operator, is ok for both lvalue and rvalue! KianString &operator=(KianString str) noexcept { swap(*this, str); return *this; }
這樣做有幾個好處:
1.參數是傳值調用,可以同時使用左值和右值,使用右值時自動調用移動拷貝函數
2.強異常安全的,異常只會發生在參數拷貝時,如果發生異常,不會影響this。
3.值傳遞產生副本,所以自賦值也是正確的.
加法運算符重載:
KianString &operator+=(const KianString &str){ ch = (char*)realloc(ch, strlen(ch)+str.size()+1); strcat(ch, str.ch); return *this; } template<typename T>
const T operator+(const T& lhs, const T& rhs) {
return T(lhs) += rhs;
}
1. 按照《c++編程規范》第27條,實現+運算符,先要實現+=,語義一致,便於維護
2. 將operator+定義為非成員函數,能夠同時接受左右參數的隱式轉換, 因為operator+=是public,所以operator+不需要設成friend。
3. 將operator+定義為template。
code:
https://github.com/coderkian/kianstring