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