跳轉到內容

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)

[編輯 | 編輯原始碼]

“指向實現的指標”(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;
}

然後從主函式呼叫

int main()
{
  Book b;
  b.print();
}

您還可以使用 std::unique_ptr<BookImpl> 或等效項來管理內部指標。

進一步閱讀

[編輯 | 編輯原始碼]
華夏公益教科書