一、 封装
作用:
封装(Encapsulation) 是面向对象编程(OOP)的核心特性之一,
把数据和操作数据的函数绑定在一起,并隐藏内部实现细节,防止外部代码直接访问对象的内部数据。
特点:
- 保护数据安全:防止外部代码直接修改数据。
- 提高代码可维护性:通过接口访问数据,修改实现时不会影响调用代码。
- 隐藏实现细节:外部代码无需关心类的内部逻辑,只需使用提供的接口。
- 增强可扩展性:可以在不修改接口的情况下改变内部实现。
二、 封装的基本实现
C++ 使用 private
、protected
、public
访问修饰符实现封装。
访问修饰符 | 作用 |
---|---|
private (默认) | 私有成员,只能在类的内部访问 |
protected | 保护成员,可在本类和子类访问 |
public | 公有成员,可被外部访问 |
示例 ——基本的封装:
#include <iostream>
using namespace std;class Person {
private:string name; // 私有成员,不能直接访问int age;protected:string habit; // 本类和子类可以访问public:// 构造函数Person(string n, int a, string s){name = n;age = a;habit = s;}// 公有接口(getter 和 setter)void setName(string n){name = n;}string getName(){return name;}void setAge(int a){if (a >= 0) age = a;}int getAge(){return age;}void setHabit(string s){habit = s;}string getHabit(){return habit;}void display(){cout << "姓名: " << name << ", 年龄: " << age << ", 爱好: " << habit << endl;}
};int main() {Person p("Alice", 25, "唱歌");// p.name = "Bob"; // 错误:name 是 private,不能直接访问// p.habit = "跳舞"; // 错误:name 是 protected,不能直接访问p.setName("Bob"); // 正确 通过公有接口修改 namep.setAge(30); // 正确 通过公有接口修改 agep.setHabit("跳舞"); // 正确 通过公有接口修改 habitcout << "姓名: " << p.getName() << endl;p.display();system("pause");return 0;
}
注意:
name
和age
设为private
,habit
设为protected
,外部无法直接访问。- 数据成员一般设为
private
,使用公有接口 来间接访问和修改数据。 protected
主要用于继承,防止外部访问,但允许子类使用。
三、 getter
和 setter
方法
getter
(访问器):获取私有成员的值。setter
(修改器):设置私有成员的值,同时可以进行数据验证。
示例 ——使用 getter
和 setter
:
#include <iostream>
using namespace std;class Car {
private:int speed;public:// 构造函数Car() { speed = 0; }// getter 方法int getSpeed() { return speed; }// setter 方法(增加数据验证)void setSpeed(int s) {if (s >= 0) speed = s;else cout << "速度不能为负数!" << endl;}
};int main() {Car car;car.setSpeed(100);cout << "当前速度: " << car.getSpeed() << " km/h" << endl;car.setSpeed(-50); // 错误 触发数据验证system("pause");return 0;
}
使用 getter
和 setter
的作用:
- 防止直接修改数据,确保数据安全性。
- 提供数据验证机制,避免非法数据输入。
四、 特殊用法
(1)友元函数(Friend Function)
作用:
友元函数(friend
) 允许某些函数访问类的 private
成员,但该函数不属于该类的成员。
示例 ——友元函数访问私有数据:
#include <iostream>
using namespace std;class Box {// 友元函数声明friend void printWidth(Box b);private:double width;public:Box(double w) { width = w; }
};// 友元函数定义
void printWidth(Box b)
{cout << "Box 宽度: " << b.width << endl; // 访问 private 成员
}int main() {Box box(10.5);printWidth(box); // 友元函数可以访问 private 数据system("pause");return 0;
}
友元函数的作用:
- 允许外部函数访问私有数据,但仍然保持封装。
- 不属于类的成员,不能用
this
访问对象。
(2)结构体 struct
的封装
在 C++ 中,struct
默认是 public
,但也可以使用 private
进行封装。
示例——使用 struct
进行封装:
struct Student {
private:string name;public:void setName(string n) { name = n; }string getName() { return name; }
};
注意:
- 简单的数据结构使用
struct
(如Point
)。 - 需要封装和继承时,使用
class
。