C++ 程式設計/習慣用法
外觀
< C++ 程式設計
T::operator=處理 LHS 和 RHS 指向同一個物件的情況。
T& operator= (const T& that)
{
if (this == &that)
return *this;
// handle assignment here
return *this;
}
筆記
- 請記住 *標識*(LHS 和 RHS 是同一個物件)和 *相等*(LHS 和 RHS 的值相同)之間的區別。T::operator=必須保護自己免受 *標識* 的影響,因為在那種情況下,賦值程式碼可以方便安全地假設 LHS 和 RHS 指向不同的物件。
- 還有其他更優秀的技術,但並非在所有情況下都適用。例如,如果類的所有成員T(比如,mem1, mem2, ..., memN)提供一個swap函式,可以使用以下程式碼代替
T& operator= (T that)
{
// that is constructed by the copy constructor
mem1.swap (that.mem1);
mem2.swap (that.mem2);
...
memN.swap (that.memN);
// now what were originally this->mem1, this->mem2, etc. get
// destroyed when that gets destroyed, and that.mem1, etc. are
// retained in *this
return *this;
}
“指向實現的指標”(pImpl)習慣用法,也稱為“不透明指標”習慣用法,是一種為類提供資料並因此進一步實現抽象的方法。
在 C++ 中,您必須在類定義中宣告成員變數,然後該變數是公開的,並且這是必要的,以便為其分配適當的記憶體空間,這意味著在“所有”類中都不可能實現抽象。
但是,以額外的指標解引用和函式呼叫為代價,您可以透過指向實現的指標獲得這種級別的抽象。
class Book
{
public:
void print();
private:
std::string m_Contents;
}
所以,使用 Book 類的人只需要瞭解 print(),但是如果您想為 Book 類新增更多細節,會發生什麼。
class Book
{
public:
void print();
private:
std::string m_Contents;
std::string m_Title;
}
現在所有使用 Book 類的人都需要重新編譯,因為他們知道的那個物件變得更大了,但他們仍然只調用 print()。
pImpl 將實現以下模式,這樣就不會出現這個問題。
/* public.h */
class Book
{
public:
Book();
~Book();
void print();
private:
class BookImpl;
BookImpl* const m_p;
}
並在一個單獨的“內部”標頭檔案中
/* private.h */
#include "public.h"
#include <iostream>
class Book::BookImpl
{
public:
void print();
private:
std::string m_Contents;
std::string m_Title;
}
然後 Book 類的主體將類似於
Book::Book(): m_p(new BookImpl())
{
}
Book::~Book()
{
delete m_p;
}
void Book::print()
{
m_p->print();
}
/* then BookImpl functions */
void Book::BookImpl::print()
{
std::cout << "print from BookImpl" << std::endl;
}
然後從 main 函式呼叫
int main()
{
Book b;
b.print();
}
您也可以使用 std::unique_ptr<BookImpl> 或等效項來管理內部指標。