C++ 封装详解

一、封装的基本概念

1.1 什么是封装

// 封装的核心思想:隐藏实现细节,提供公共接口
class EncapsulationBasics {
private:
    // 数据隐藏:内部实现细节
    int internalData;
    double sensitiveInfo;
    std::vector<int> privateBuffer;
    
    // 私有辅助方法
    void validateData(int value) {
        if (value < 0 || value > 100) {
            throw std::invalid_argument("Value out of range");
        }
    }
    
    void updateInternalState() {
        // 内部状态更新逻辑
        sensitiveInfo = internalData * 2.5;
    }
    
public:
    // 公共接口:对外提供的功能
    void setValue(int value) {
        validateData(value);        // 内部验证
        internalData = value;       // 设置值
        updateInternalState();      // 更新相关状态
    }
    
    int getValue() const {
        return internalData;        // 受控的访问
    }
    
    // 只提供必要的操作,不暴露内部结构
    void processData() {
        // 用户不需要知道具体如何处理
        for (auto& item : privateBuffer) {
            item *= 2;
        }
    }
};
 
// 封装的好处演示
class BankAccount {
private:
    double balance;           // 余额不能直接访问
    std::string accountNumber;
    std::vector<std::string> transactionHistory;
    static double interestRate;
    
    // 内部验证方法
    bool isValidAmount(double amount) const {
        return amount > 0 && amount <= balance;
    }
    
    void recordTransaction(const std::string& type, double amount) {
        auto now = std::chrono::system_clock::now();
        auto time = std::chrono::system_clock::to_time_t(now);
        std::stringstream ss;
        ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S");
        ss << " - " << type << ": $" << amount;
        transactionHistory.push_back(ss.str());
    }
    
public:
    BankAccount(const std::string& accNum, double initialDeposit) 
        : accountNumber(accNum), balance(0) {
        if (initialDeposit > 0) {
            balance = initialDeposit;
            recordTransaction("Initial Deposit", initialDeposit);
        }
    }
    
    // 安全的取款操作
    bool withdraw(double amount) {
        if (amount <= 0) {
            return false;  // 无效金额
        }
        if (amount > balance) {
            return false;  // 余额不足
        }
        
        balance -= amount;
        recordTransaction("Withdrawal", amount);
        return true;
    }
    
    // 安全的存款操作
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            recordTransaction("Deposit", amount);
        }
    }
    
    // 只读访问
    double getBalance() const { return balance; }
    
    // 获取交易历史(返回副本,保护原始数据)
    std::vector<std::string> getTransactionHistory() const {
        return transactionHistory;  // 返回副本
    }
};

1.2 封装的层次

class EncapsulationLevels {
    // 类级别封装
    class ClassLevel {
    private:
        int privateData;      // 只能被本类访问
    protected:
        int protectedData;    // 能被本类和派生类访问
    public:
        int publicData;       // 任何地方都能访问
    };
    
    // 模块级别封装(使用命名空间)
    namespace Internal {
        // 内部实现细节
        namespace Detail {
            class InternalHelper {
                // 不应该被外部使用的类
            };
        }
        
        // 模块内部接口
        class ModuleInterface {
        public:
            void publicFunction();
        };
    }
    
    // 文件级别封装(使用匿名命名空间)
    namespace {
        // 只在当前编译单元可见
        class FileLocalClass {
            void fileLocalFunction() {}
        };
    }
};

二、数据封装技术

2.1 Getter和Setter设计

class GetterSetterDesign {
private:
    int simpleValue;
    double cachedValue;
    mutable bool cacheValid;
    std::string name;
    std::vector<int> data;
    
public:
    // 1. 简单的getter/setter
    int getSimpleValue() const { return simpleValue; }
    void setSimpleValue(int value) { simpleValue = value; }
    
    // 2. 带验证的setter
    bool setName(const std::string& newName) {
        if (newName.empty() || newName.length() > 50) {
            return false;  // 验证失败
        }
        name = newName;
        return true;
    }
    
    // 3. 计算属性(懒加载)
    double getComputedValue() const {
        if (!cacheValid) {
            cachedValue = expensiveComputation();
            cacheValid = true;
        }
        return cachedValue;
    }
    
    // 4. 返回const引用(避免拷贝)
    const std::string& getName() const { return name; }
    
    // 5. 链式调用的setter
    GetterSetterDesign& setValue(int value) {
        simpleValue = value;
        cacheValid = false;  // 使缓存无效
        return *this;
    }
    
    // 6. 属性风格的访问(使用函数对象)
    class Property {
    private:
        int& ref;
        std::function<bool(int)> validator;
        std::function<void()> onChange;
        
    public:
        Property(int& r, 
                std::function<bool(int)> v = [](int){return true;},
                std::function<void()> c = [](){})
            : ref(r), validator(v), onChange(c) {}
        
        operator int() const { return ref; }
        
        Property& operator=(int value) {
            if (validator(value)) {
                ref = value;
                onChange();
            }
            return *this;
        }
    };
    
private:
    double expensiveComputation() const {
        // 模拟昂贵的计算
        return simpleValue * 3.14159;
    }
};
 
// 高级属性系统
template<typename T>
class Property {
private:
    T value;
    std::function<void(const T&, const T&)> onChanged;
    std::function<bool(const T&)> validator;
    
public:
    Property(const T& initial = T{}) : value(initial) {}
    
    // 设置变化回调
    Property& onChange(std::function<void(const T&, const T&)> callback) {
        onChanged = callback;
        return *this;
    }
    
    // 设置验证器
    Property& validate(std::function<bool(const T&)> v) {
        validator = v;
        return *this;
    }
    
    // getter
    const T& get() const { return value; }
    operator const T&() const { return value; }
    
    // setter
    bool set(const T& newValue) {
        if (validator && !validator(newValue)) {
            return false;
        }
        
        T oldValue = value;
        value = newValue;
        
        if (onChanged) {
            onChanged(oldValue, newValue);
        }
        return true;
    }
    
    Property& operator=(const T& newValue) {
        set(newValue);
        return *this;
    }
};

2.2 不可变对象设计

class ImmutableObject {
    // 不可变类设计
    class ImmutableString {
    private:
        const std::string data;
        const size_t hashCode;
        
        static size_t computeHash(const std::string& str) {
            return std::hash<std::string>{}(str);
        }
        
    public:
        explicit ImmutableString(const std::string& str) 
            : data(str), hashCode(computeHash(str)) {}
        
        // 只提供const方法
        const std::string& get() const { return data; }
        size_t hash() const { return hashCode; }
        
        // 修改操作返回新对象
        ImmutableString concat(const ImmutableString& other) const {
            return ImmutableString(data + other.data);
        }
        
        ImmutableString substring(size_t start, size_t length) const {
            return ImmutableString(data.substr(start, length));
        }
        
        // 删除赋值运算符
        ImmutableString& operator=(const ImmutableString&) = delete;
    };
    
    // 不可变集合
    template<typename T>
    class ImmutableVector {
    private:
        const std::vector<T> data;
        
    public:
        explicit ImmutableVector(std::vector<T> vec) 
            : data(std::move(vec)) {}
        
        // 只读访问
        size_t size() const { return data.size(); }
        const T& operator[](size_t index) const { return data[index]; }
        
        // 修改操作返回新对象
        ImmutableVector add(const T& item) const {
            std::vector<T> newData = data;
            newData.push_back(item);
            return ImmutableVector(std::move(newData));
        }
        
        ImmutableVector remove(size_t index) const {
            if (index >= data.size()) {
                return *this;
            }
            std::vector<T> newData = data;
            newData.erase(newData.begin() + index);
            return ImmutableVector(std::move(newData));
        }
        
        // 迭代器(只读)
        auto begin() const { return data.begin(); }
        auto end() const { return data.end(); }
    };
};

三、接口设计与信息隐藏

3.1 最小接口原则

class MinimalInterface {
    // 错误示例:过度暴露
    class BadDesign {
    public:
        std::vector<int> data;  // 直接暴露内部数据结构
        
        void sortData() { std::sort(data.begin(), data.end()); }
        void reverseData() { std::reverse(data.begin(), data.end()); }
        void shuffleData() { /* ... */ }
        void rotateLeft() { /* ... */ }
        void rotateRight() { /* ... */ }
        // 太多不必要的公共方法
    };
    
    // 正确示例:最小化接口
    class GoodDesign {
    private:
        std::vector<int> data;
        
        // 内部辅助方法
        void ensureSorted() {
            if (!std::is_sorted(data.begin(), data.end())) {
                std::sort(data.begin(), data.end());
            }
        }
        
    public:
        // 只暴露必要的操作
        void add(int value) {
            data.push_back(value);
        }
        
        bool remove(int value) {
            auto it = std::find(data.begin(), data.end(), value);
            if (it != data.end()) {
                data.erase(it);
                return true;
            }
            return false;
        }
        
        bool contains(int value) const {
            return std::find(data.begin(), data.end(), value) != data.end();
        }
        
        size_t size() const { return data.size(); }
        bool empty() const { return data.empty(); }
    };
};

3.2 Pimpl惯用法(编译防火墙)

// Widget.h - 公共接口
class Widget {
    class Impl;  // 前向声明
    std::unique_ptr<Impl> pImpl;  // 指向实现的指针
    
public:
    // 公共接口
    Widget();
    ~Widget();  // 必须在源文件中定义
    
    Widget(const Widget& other);
    Widget& operator=(const Widget& other);
    Widget(Widget&& other) noexcept;
    Widget& operator=(Widget&& other) noexcept;
    
    void doSomething();
    int getValue() const;
    void setValue(int value);
};
 
// Widget.cpp - 实现细节
#include "Widget.h"
#include <map>
#include <algorithm>
// 可以包含任何头文件,不会影响使用Widget的代码
 
class Widget::Impl {
private:
    int value;
    std::string name;
    std::map<std::string, int> cache;
    std::vector<double> internalData;
    
public:
    Impl() : value(0), name("default") {}
    
    Impl(const Impl& other) 
        : value(other.value)
        , name(other.name)
        , cache(other.cache)
        , internalData(other.internalData) {}
    
    void doSomething() {
        // 复杂的实现
        value++;
        cache[name] = value;
        internalData.push_back(value * 1.5);
    }
    
    int getValue() const { return value; }
    void setValue(int v) { value = v; }
};
 
// Widget成员函数实现
Widget::Widget() : pImpl(std::make_unique<Impl>()) {}
Widget::~Widget() = default;  // 必须在Impl完整定义后
 
Widget::Widget(const Widget& other) 
    : pImpl(std::make_unique<Impl>(*other.pImpl)) {}
 
Widget& Widget::operator=(const Widget& other) {
    if (this != &other) {
        pImpl = std::make_unique<Impl>(*other.pImpl);
    }
    return *this;
}
 
Widget::Widget(Widget&& other) noexcept = default;
Widget& Widget::operator=(Widget&& other) noexcept = default;
 
void Widget::doSomething() { pImpl->doSomething(); }
int Widget::getValue() const { return pImpl->getValue(); }
void Widget::setValue(int value) { pImpl->setValue(value); }

四、访问控制策略

4.1 友元的合理使用

class FriendUsage {
    // 运算符重载的友元
    class Complex {
    private:
        double real, imag;
        
    public:
        Complex(double r = 0, double i = 0) : real(r), imag(i) {}
        
        // 友元函数用于运算符重载
        friend Complex operator+(const Complex& a, const Complex& b);
        friend Complex operator*(const Complex& a, const Complex& b);
        friend std::ostream& operator<<(std::ostream& os, const Complex& c);
        
        // 友元类用于紧密相关的类
        friend class ComplexBuilder;
    };
    
    Complex operator+(const Complex& a, const Complex& b) {
        return Complex(a.real + b.real, a.imag + b.imag);
    }
    
    // Builder模式的友元使用
    class ComplexBuilder {
    private:
        Complex result;
        
    public:
        ComplexBuilder& setReal(double r) {
            result.real = r;  // 可以访问Complex的私有成员
            return *this;
        }
        
        ComplexBuilder& setImag(double i) {
            result.imag = i;
            return *this;
        }
        
        Complex build() { return result; }
    };
    
    // Attorney-Client惯用法(受控友元)
    class Document {
    private:
        std::string content;
        
        void internalSave() { /* ... */ }
        void internalLoad() { /* ... */ }
        
        friend class DocumentAttorney;
    };
    
    class DocumentAttorney {
    private:
        friend class DocumentSaver;
        friend class DocumentLoader;
        
        static void save(Document& doc) { doc.internalSave(); }
        static void load(Document& doc) { doc.internalLoad(); }
    };
    
    class DocumentSaver {
    public:
        void saveDocument(Document& doc) {
            DocumentAttorney::save(doc);  // 受控访问
        }
    };
};

4.2 嵌套类的封装

class NestedClassEncapsulation {
    class Container {
    private:
        // 私有嵌套类,完全隐藏实现
        class Node {
            int data;
            Node* next;
        public:
            Node(int d) : data(d), next(nullptr) {}
        };
        
        Node* head;
        
    public:
        // 公共嵌套类,作为接口的一部分
        class Iterator {
        private:
            Node* current;
            
            Iterator(Node* node) : current(node) {}
            friend class Container;
            
        public:
            int operator*() const { return current->data; }
            Iterator& operator++() {
                current = current->next;
                return *this;
            }
            bool operator!=(const Iterator& other) const {
                return current != other.current;
            }
        };
        
        Container() : head(nullptr) {}
        
        void push_front(int value) {
            Node* newNode = new Node(value);
            newNode->next = head;
            head = newNode;
        }
        
        Iterator begin() { return Iterator(head); }
        Iterator end() { return Iterator(nullptr); }
    };
};

五、高级封装技术

5.1 CRTP(奇异递归模板模式)封装

template<typename Derived>
class CRTPBase {
protected:
    // 受保护的实现细节
    void implementationDetail() {
        std::cout << "Base implementation\n";
    }
    
public:
    // 公共接口
    void publicInterface() {
        // 前置处理
        std::cout << "Before derived\n";
        
        // 调用派生类实现
        static_cast<Derived*>(this)->implementation();
        
        // 后置处理
        std::cout << "After derived\n";
    }
    
    // 提供默认实现
    void implementation() {
        implementationDetail();
    }
};
 
class CRTPDerived : public CRTPBase<CRTPDerived> {
public:
    // 覆盖实现
    void implementation() {
        std::cout << "Derived implementation\n";
    }
};
 
// Mixin模式的封装
template<typename T>
class Printable {
public:
    void print() const {
        static_cast<const T*>(this)->printImpl();
    }
    
protected:
    void printImpl() const {
        std::cout << "Default print\n";
    }
};
 
template<typename T>
class Serializable {
public:
    std::string serialize() const {
        return static_cast<const T*>(this)->serializeImpl();
    }
    
protected:
    std::string serializeImpl() const {
        return "default";
    }
};
 
class MyClass : public Printable<MyClass>, 
                public Serializable<MyClass> {
public:
    void printImpl() const {
        std::cout << "MyClass print\n";
    }
    
    std::string serializeImpl() const {
        return "MyClass data";
    }
};

5.2 策略模式封装

class StrategyEncapsulation {
    // 策略接口
    class SortStrategy {
    public:
        virtual ~SortStrategy() = default;
        virtual void sort(std::vector<int>& data) = 0;
    };
    
    // 具体策略(实现细节)
    class QuickSort : public SortStrategy {
    public:
        void sort(std::vector<int>& data) override {
            // QuickSort实现
            std::sort(data.begin(), data.end());
        }
    };
    
    class MergeSort : public SortStrategy {
    public:
        void sort(std::vector<int>& data) override {
            // MergeSort实现
            std::stable_sort(data.begin(), data.end());
        }
    };
    
    // 上下文类
    class DataProcessor {
    private:
        std::vector<int> data;
        std::unique_ptr<SortStrategy> sortStrategy;
        
    public:
        DataProcessor() 
            : sortStrategy(std::make_unique<QuickSort>()) {}
        
        void setSortStrategy(std::unique_ptr<SortStrategy> strategy) {
            sortStrategy = std::move(strategy);
        }
        
        void addData(int value) {
            data.push_back(value);
        }
        
        void process() {
            sortStrategy->sort(data);  // 使用策略
        }
        
        void display() const {
            for (int val : data) {
                std::cout << val << " ";
            }
            std::cout << "\n";
        }
    };
};

5.3 代理模式封装

class ProxyPattern {
    // 真实对象接口
    class Image {
    public:
        virtual ~Image() = default;
        virtual void display() = 0;
        virtual std::string getName() const = 0;
    };
    
    // 真实对象(重量级)
    class RealImage : public Image {
    private:
        std::string filename;
        std::vector<unsigned char> imageData;
        
        void loadFromDisk() {
            std::cout << "Loading image: " << filename << "\n";
            // 模拟加载大图片
            imageData.resize(1024 * 1024);  // 1MB
        }
        
    public:
        explicit RealImage(const std::string& file) 
            : filename(file) {
            loadFromDisk();
        }
        
        void display() override {
            std::cout << "Displaying: " << filename << "\n";
        }
        
        std::string getName() const override {
            return filename;
        }
    };
    
    // 代理对象(轻量级)
    class ProxyImage : public Image {
    private:
        std::string filename;
        mutable std::unique_ptr<RealImage> realImage;
        
    public:
        explicit ProxyImage(const std::string& file) 
            : filename(file) {}
        
        void display() override {
            if (!realImage) {
                realImage = std::make_unique<RealImage>(filename);
            }
            realImage->display();
        }
        
        std::string getName() const override {
            return filename;  // 不需要加载真实图片
        }
    };
    
    // 智能指针代理
    template<typename T>
    class SmartProxy {
    private:
        T* ptr;
        mutable size_t accessCount;
        
    public:
        explicit SmartProxy(T* p) : ptr(p), accessCount(0) {}
        
        T* operator->() const {
            ++accessCount;
            std::cout << "Access count: " << accessCount << "\n";
            return ptr;
        }
        
        T& operator*() const {
            ++accessCount;
            return *ptr;
        }
        
        size_t getAccessCount() const { return accessCount; }
    };
};

六、封装的最佳实践

6.1 接口稳定性

class InterfaceStability {
    // 版本1:初始设计
    class ServiceV1 {
    private:
        struct Impl;
        std::unique_ptr<Impl> pImpl;
        
    public:
        ServiceV1();
        ~ServiceV1();
        
        void operation1();
        void operation2();
    };
    
    // 版本2:添加新功能(保持向后兼容)
    class ServiceV2 {
    private:
        struct Impl;
        std::unique_ptr<Impl> pImpl;
        
    public:
        ServiceV2();
        ~ServiceV2();
        
        // 保留原有接口
        void operation1();
        void operation2();
        
        // 新增功能
        void operation3();
        
        // 带默认参数的新版本
        void operation1(int param = 0);
    };
    
    // 使用版本控制
    class VersionedAPI {
    public:
        enum class Version { V1, V2, V3 };
        
    private:
        Version currentVersion;
        
    public:
        explicit VersionedAPI(Version v = Version::V3) 
            : currentVersion(v) {}
        
        void execute() {
            switch (currentVersion) {
                case Version::V1:
                    executeV1();
                    break;
                case Version::V2:
                    executeV2();
                    break;
                case Version::V3:
                    executeV3();
                    break;
            }
        }
        
    private:
        void executeV1() { /* V1 implementation */ }
        void executeV2() { /* V2 implementation */ }
        void executeV3() { /* V3 implementation */ }
    };
};

6.2 封装的度量标准

class EncapsulationMetrics {
    // 高内聚的类
    class HighCohesion {
    private:
        std::string data;
        
        // 所有方法都操作同一组数据
        void validateData() { /* ... */ }
        void processData() { /* ... */ }
        void formatData() { /* ... */ }
        
    public:
        void setData(const std::string& d) {
            data = d;
            validateData();
        }
        
        std::string getData() {
            processData();
            formatData();
            return data;
        }
    };
    
    // 低耦合的设计
    class LowCoupling {
        // 依赖接口而不是具体实现
        class DataSource {
        public:
            virtual ~DataSource() = default;
            virtual std::string read() = 0;
        };
        
        class DataProcessor {
        private:
            std::unique_ptr<DataSource> source;
            
        public:
            explicit DataProcessor(std::unique_ptr<DataSource> s)
                : source(std::move(s)) {}
            
            void process() {
                std::string data = source->read();  // 低耦合
                // 处理数据
            }
        };
    };
    
    // 信息隐藏度量
    class InformationHiding {
    public:
        // 公共接口复杂度:低
        void simpleOperation();
        
    private:
        // 实现复杂度:高(被隐藏)
        void complexAlgorithm1();
        void complexAlgorithm2();
        void complexAlgorithm3();
        
        // 数据复杂度:高(被隐藏)
        std::map<std::string, std::vector<int>> complexData;
        std::unordered_map<int, std::shared_ptr<void>> cache;
    };
};

6.3 封装的性能考虑

class PerformanceConsiderations {
    // 内联封装
    class InlineEncapsulation {
    private:
        int value;
        
    public:
        // 简单的getter/setter可以内联
        inline int getValue() const { return value; }
        inline void setValue(int v) { value = v; }
        
        // 复杂操作不应内联
        void complexOperation();  // 定义在源文件中
    };
    
    // 零成本抽象
    template<typename T>
    class ZeroCostWrapper {
    private:
        T value;
        
    public:
        explicit ZeroCostWrapper(T v) : value(v) {}
        
        // 编译时优化掉的封装
        T& get() { return value; }
        const T& get() const { return value; }
        
        // 操作符重载保持自然语法
        operator T&() { return value; }
        operator const T&() const { return value; }
    };
    
    // 缓存友好的封装
    class CacheFriendly {
    private:
        // 热数据放在一起
        struct HotData {
            int frequently_used1;
            int frequently_used2;
            double frequently_used3;
        } hot;
        
        // 冷数据分离
        struct ColdData {
            std::string rarely_used1;
            std::vector<int> rarely_used2;
        };
        std::unique_ptr<ColdData> cold;
        
    public:
        int getFrequent() const { return hot.frequently_used1; }
        
        const std::string& getRare() {
            if (!cold) {
                cold = std::make_unique<ColdData>();
            }
            return cold->rarely_used1;
        }
    };
};

6.4 测试友好的封装

class TestFriendlyEncapsulation {
    // 依赖注入
    class EmailService {
    public:
        virtual ~EmailService() = default;
        virtual void sendEmail(const std::string& to, 
                              const std::string& message) = 0;
    };
    
    class UserManager {
    private:
        std::unique_ptr<EmailService> emailService;
        
    public:
        explicit UserManager(std::unique_ptr<EmailService> service)
            : emailService(std::move(service)) {}
        
        void registerUser(const std::string& email) {
            // 业务逻辑
            emailService->sendEmail(email, "Welcome!");
        }
    };
    
    // 测试用的Mock对象
    class MockEmailService : public EmailService {
    public:
        mutable std::vector<std::pair<std::string, std::string>> sentEmails;
        
        void sendEmail(const std::string& to, 
                      const std::string& message) override {
            sentEmails.push_back({to, message});
        }
    };
    
    // 部分暴露用于测试
    class TestableClass {
    private:
        int privateState;
        
    protected:
        // 为测试类提供访问
        virtual int getStateForTesting() const { return privateState; }
        
    public:
        void publicMethod() {
            privateState = 42;
        }
        
        friend class TestableClassTest;  // 测试友元
    };
};