C++ OOP 面试高频知识点 - 02
封装思想,C++ 实现私有化成员 + get/set 接口
1. 封装的基本概念
封装(Encapsulation) 是面向对象编程的核心原则之一,它将数据(成员变量)和操作数据的方法(成员函数)结合在一起,形成一个独立的实体(对象),并对外部世界隐藏对象的内部实现细节。
封装的主要目的是: - 提高代码的可维护性 - 提高代码的安全性 - 简化编程接口
2. C++ 中的封装实现
在 C++ 中,我们通过访问控制关键字来实现封装,通常将成员变量设置为 private 或 protected,并提供公共的 get 和 set 接口来访问这些成员变量。
class Person {
private:
string name;
int age;
string address;
public:
// 获取姓名
string getName() const {
return name;
}
// 设置姓名
void setName(const string& newName) {
name = newName;
}
// 获取年龄
int getAge() const {
return age;
}
// 设置年龄,添加范围验证
void setAge(int newAge) {
if (newAge >= 0 && newAge <= 150) {
age = newAge;
} else {
cout << "Invalid age!" << endl;
}
}
// 获取地址
string getAddress() const {
return address;
}
// 设置地址
void setAddress(const string& newAddress) {
address = newAddress;
}
};
3. get 和 set 接口的设计原则
3.1 命名规范
get方法通常以get开头,后跟成员变量名(首字母大写)set方法通常以set开头,后跟成员变量名(首字母大写)- 对于布尔值,
get方法也可以以is开头
class MyClass {
private:
bool active;
public:
bool isActive() const {
return active;
}
void setActive(bool value) {
active = value;
}
};
3.2 访问修饰符
get方法通常是const成员函数,表示不会修改对象状态set方法通常接受const引用参数,以避免不必要的拷贝
void setName(const string& newName) { // 使用 const 引用
name = newName;
}
string getName() const { // const 成员函数
return name;
}
3.3 验证和错误处理
在 set 方法中可以添加验证逻辑,确保成员变量的值在有效范围内:
void setAge(int newAge) {
if (newAge >= 0 && newAge <= 150) {
age = newAge;
} else {
throw invalid_argument("Age must be between 0 and 150");
}
}
4. 封装的优势
4.1 信息隐藏
通过封装,我们可以隐藏类的内部实现细节,只暴露必要的接口给外部世界。
4.2 代码维护性
如果我们需要修改类的内部实现,只要保持公共接口不变,外部代码就不需要修改。
// 内部实现变更,但接口保持不变
void setAge(int newAge) {
if (newAge >= 0 && newAge <= 120) { // 修改了年龄上限
age = newAge;
} else {
throw invalid_argument("Age must be between 0 and 120");
}
}
4.3 代码安全性
通过 set 方法的验证逻辑,我们可以确保成员变量的值始终是有效的。
5. 常见问题和回答
问题 1:为什么要将成员变量设置为 private?
将成员变量设置为 private 可以防止外部代码直接修改它们,从而避免了错误的修改和数据不一致性。
问题 2:什么时候应该使用 public 成员变量?
只有在变量是不可变的(const)或非常简单且安全的情况下,才应该使用 public 成员变量。
class Constants {
public:
static const int MAX_VALUE = 100;
static const double PI = 3.14159;
};
问题 3:封装会影响性能吗?
通常情况下,封装不会显著影响性能。现代编译器会优化简单的 get 和 set 方法,使其与直接访问成员变量的性能几乎相同。
总结
封装是 C++ 面向对象编程的核心原则之一。通过将成员变量设置为 private 或 protected,并提供公共的 get 和 set 接口,我们可以提高代码的可维护性、安全性和复用性。
练习建议:
1. 设计一个 BankAccount 类,包含账户余额和交易记录
2. 实现存款和取款功能,并添加余额验证
3. 提供查询余额和交易记录的接口