封装
封装的核心概念
封装是面向对象编程(OOP)的三大特性之一(另外两个是继承和多态),其核心思想是将数据(属性)和操作数据的方法(行为)绑定为一个独立的单元(类),并通过访问控制隐藏内部实现细节,仅对外提供可控的接口。这种设计模式确保了数据的安全性、代码的可维护性和可扩展性。
封装的两层含义:
数据与行为的结合
将描述对象状态的成员变量(如圆的半径)和操作这些变量的成员函数(如计算面积)组合在同一个类中,形成逻辑上的整体。例如:1
2
3
4
5
6
7class Circle {
private:
double radius; // 数据成员
public:
void setRadius(double r) { radius = r; } // 行为成员
double getArea() { return 3.14 * radius * radius; }
};访问控制与信息隐藏
通过访问修饰符(public、protected、private)控制成员的可见性,强制外部代码只能通过公共接口交互,避免直接操作内部数据。例如:1
2
3
4
5
6
7class Person {
private:
int age; // 私有成员,外部无法直接访问
public:
void setAge(int a) { if (a > 0) age = a; } // 带验证的公共接口
int getAge() const { return age; }
};
访问控制的深度解析
C++提供三种访问修饰符,精确控制类成员的访问范围:
| 修饰符 | 类内访问 | 类外访问 | 派生类访问 |
|---|---|---|---|
public |
✅ | ✅ | ✅ |
protected |
✅ | ❌ | ✅(仅限子类) |
private |
✅ | ❌ | ❌ |
实践建议:
- 默认私有原则:所有成员默认设为
private,仅将必要的接口暴露为public。 - 数据私有化:成员变量必须为
private,通过getter/setter控制访问,确保数据合法性。 - 审慎使用
protected:仅在明确需要子类直接访问时使用,避免破坏封装。
示例:通过访问控制实现读写权限细分
1 | class Person { |
封装的关键技术实现
类的声明与实现分离
将类的声明(接口)放在头文件(.h),实现(细节)放在源文件(.cpp),降低编译依赖。例如:
1 | // Person.h |
友元函数与友元类
允许特定外部函数或类访问私有成员,需谨慎使用以避免破坏封装。
1 | class Rectangle { |
RAII(资源获取即初始化)
通过构造函数获取资源,析构函数释放资源,确保异常安全。例如:
1 | class FileHandle { |
高级封装技巧
Pimpl Idiom(指针指向实现)
将私有成员隐藏在实现类中,头文件仅保留指针,减少编译依赖。
1 | // Widget.h(接口类) |
委托构造函数(C++11)
构造函数间相互调用,简化代码:
1 | class Employee { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 山川不念旧!
评论


