这种设计模式通常被称为 Pimpl(Pointer to Implementation)惯用法 ,有时也被称为 Cheshire Cat 惯用法。它主要用于隐藏实现细节和减少编译依赖。
例子:
DatabaseConnection.h
cpp
#ifndef DATABASE_CONNECTION_H
#define DATABASE_CONNECTION_H
#include <string>
class DatabaseConnection {
public:
DatabaseConnection(const std::string& connectionString);
~DatabaseConnection();
void connect();
void disconnect();
bool isConnected() const;
private:
class Impl; // 前向声明
Impl* pImpl; // 指向实现类的指针
};
#endif // DATABASE_CONNECTION_H
DatabaseConnection.cpp
cpp
#include "DatabaseConnection.h"
#include <iostream>
// 实现类
class DatabaseConnection::Impl {
public:
Impl(const std::string& connStr) : connectionString(connStr), connected(false) {}
void connect() {
// 模拟连接数据库
std::cout << "Connecting to database with connection string: " << connectionString << std::endl;
connected = true;
}
void disconnect() {
// 模拟断开数据库连接
std::cout << "Disconnecting from database." << std::endl;
connected = false;
}
bool isConnected() const {
return connected;
}
private:
std::string connectionString;
bool connected;
};
// DatabaseConnection类的实现
DatabaseConnection::DatabaseConnection(const std::string& connectionString)
: pImpl(new Impl(connectionString)) {}
DatabaseConnection::~DatabaseConnection() {
delete pImpl;
}
void DatabaseConnection::connect() {
pImpl->connect();
}
void DatabaseConnection::disconnect() {
pImpl->disconnect();
}
bool DatabaseConnection::isConnected() const {
return pImpl->isConnected();
}
这个例子的要点:
- 信息隐藏 :
DatabaseConnection
的用户不需要知道连接是如何实现的,只需要知道如何使用接口。 - 减少编译依赖 :
Impl
类的定义在源文件中,头文件中只需要前向声明。 - 灵活性 :如果需要更改连接的实现(例如,切换到不同的数据库库),只需修改
Impl
类,而不影响DatabaseConnection
的接口。
这种模式特别适合需要频繁更改实现细节的类,因为它可以在不影响接口的情况下进行更改。