PIMPL(二)


文檔下載

上一篇文檔,PIMPL(一)

1 如何使用PIMPL

  有多種方式實現PIMPL,這里按照《Effective C++》中介紹的方式。

  1.1 基本步驟

  假設原有Person如下:

Person.h

struct Person
{
 public:
  Person(const int _age);
  void print();

 private:
  int age;
};

 Person.cc

Person::Person(const int _age)
    : age(_age)
{}

void
Person::print()
{
  std::cout << "Person::print::age=" << age << std::endl;
}

    1.1.1 將Person改名為PersonImpl

PersonImpl.h

struct PersonImpl
{
 public:
  PersonImpl(const int _age);
  void print();

 private:
  int age;
};

 PersonImpl.cc

PersonImpl::PersonImpl(const int _age)
    : age(_age)
{}

void
PersonImpl::print()
{
  std::cout << "PersonImpl::print::age=" << age << std::endl;
}

    1.1.2 抽象public和protected方法

  將PersonImpl中的public和protected方法成Person。Person中的方法實際調用的是PersonImpl中對應的方法,Person的定義中需要使用PersonImpl,在Person.h文件中絕對不能#include “PersonImpl.h”,這樣就是做無用功了。

  • 為什么不能將PersonImpl的對象作為Person的成員變量?

  因為Person類的定義中需要知道該類的大小,如果直接使用PersonImpl的對象,那么就必須知道PersonImpl的定義,而我們恰恰希望在Person的定義中隱藏PersonImpl的定義。這時候,指針就大顯神通了。因為指針的大小只與操作系統的位數有關(32位的機器都占4個字節,64位的機器都占8個字節),所以我們可以使用指針指向PersonImpl,從而只需要前置聲明就可以了。這就是暗度陳倉吧。

Person.h

struct PersonImpl;  // 前置聲明,PIMPL的關鍵

struct Person
{
 public:
  Person(const int _age);
  void print();

 private:
  std::shared_ptr<PersonImpl> pImpl;  // 指針,暗度陳倉
};

 Person.cc

Person::Person(const int _age)
    : pImpl(new PersonImpl(_age))
{}

void
Person::print()
{
  pImpl->print();
}

    1.1.3 使用Person

  在其它地方我們就可以使用Person了,例如:

int main()
{
  Person p(1);
  p.print();
  
  return 0;
}

    1.1.4     示例源碼下載

2 優缺點

  2.1 優點

  • 改變類的私有成員無需重新編譯依賴它的文件,所以整個工程重新編譯的速度會快很多。
  • 頭文件中采用聲明式,因此編譯時間會快很多。
  • 接口與實現的分離,更有利於單元測試。

  2.2 缺點

  • 實現者需要做更多的工作。
  • 代碼會變得不易理解。
  • 運行時動態的獲取要執行的方法,性能降低。
  • 需要注意定義拷貝構造換函數或將其禁用。

3 總結

  如《Effective C++》中所說:

  •   如果使用object reference或object pointers可以完成任務,就不要使用objects
  •   盡量以class聲明式替換class定義式

4 參考

  1. 《effective C++》 條款31:將文件間的編譯關系降至最低
  2. PIMPL Idiom: http://c2.com/cgi/wiki?PimplIdiom


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM