首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ PIMPL 惯用法:接口與實現分離

     編輯:關於C++

動機

類定義中若包含私有數據成員,任何修改(增減成員、改變類型)都會導致所有包含該頭文件的編譯單元重新編譯。PIMPL(Pointer to IMPLementation)將實現細節隱藏至 `.cpp` 文件,實現「編譯期防火牆」。

模式結構

  • 公共頭文件 `Public.h`:定義 `Handle` 類(如 `Book`),僅含公共接口與一個指向 `Impl` 的指針 `pimpl`,`Impl` 前置聲明為私有內嵌類。
  • 私有頭文件 `Private.h`:定義 `Impl` 類(`Book::BookImpl`),包含所有數據成員與實現邏輯。
  • 實現文件 `Book.cpp`:包含 `Private.h`,實現 `Handle` 的轉發函數與 `Impl` 的成員函數。

代碼示例

// Public.h
#ifndef PUBLIC_H
#define PUBLIC_H
class Book {
public:
    Book(); ~Book();
    void print();
private:
    class BookImpl;          // 前置聲明
    BookImpl* pimpl;         // 不完整類型,僅指針
};
#endif
// Private.h
#ifndef PRIVATE_H
#define PRIVATE_H
#include "Public.h"
#include 
class Book::BookImpl {
public:
    void print();
private:
    std::string contents;
    std::string title;
};
#endif
// Book.cpp
#include "Private.h"
#include 
Book::Book() : pimpl(new BookImpl()) {}
Book::~Book() { delete pimpl; }
void Book::print() { pimpl->print(); }
void Book::BookImpl::print() {
    std::cout << "Print from BookImpl\n";
}
// main.cpp
#include "Public.h"
int main() {
    Book book;
    book.print();
    return 0;
}

優缺點權衡

優點缺點
隱藏實現細節,減少編譯依賴,加快編譯每次成員訪問多一次指針間接引用
二進制兼容:修改私有成員不需重鏈接用戶代碼每個對象額外一指針內存開銷
接口穩定,便於庫發布需手動實現拷貝/移動語義(深拷貝 `pimpl`)

現代 C++ 改進

  • 使用 `std::unique_ptr` 管理生命週期,自動處理拷貝/移動(需自定義)。
  • C++20 `std::pimpl` 提案(尚未標準化)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved