C++ 中的访问控制符
本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 34 课,共 104 课。
C++ 提供了三种访问修饰符,用于控制谁可以访问类成员:public、protected 和 private。它们构成了封装的基础。
class Account {
public:
std::string ownerName; // 可以从任何地方访问
protected:
double interestRate; // 可以在此类及其派生类中访问
private:
double balance; // 只能在此类内部访问
};公有成员可以从任何地方访问,包括类内部、派生类以及外部代码。私有成员的限制最严格,只能在类本身内部访问。受保护介于两者之间:对外部代码来说,它的作用类似于私有成员,但派生类可以访问这些成员。
class Account {
private:
double balance;
public:
Account() : balance(0) {}
void deposit(double amount) {
balance += amount; // 可以,在类内部
}
};
int main() {
Account acc;
acc.deposit(100); // 可以,deposit 是公有的
// acc.balance = 500; // 错误:balance 是私有的
}默认情况下,如果没有指定访问修饰符,类中的所有成员都是私有的。这样可以鼓励你明确决定要公开哪些内容。通常的做法是将数据成员设为私有,并提供公有方法,以便安全地与它们交互。
挑战
简单让我们构建一个简单的员工管理系统,演示访问修饰符如何控制谁能访问哪些内容。你将创建一个类,其中一些数据完全私有,一些数据可供可能的派生类访问,还有一些数据对所有人开放。
你将创建两个文件来组织代码:
Employee.h:定义一个使用全部三种访问修饰符来恰当保护数据的Employee类:- Public:员工的
name(字符串)。可以从任何位置访问 - Protected:员工的
department(字符串):可在类内部以及派生类中访问,但不能从类外部访问 - Private:员工的
salary(double):只能在类内部访问 - 一个构造函数,接收 name、department 和 salary,并初始化这三个成员
- 一个公有方法
getSalary(),返回私有的 salary 值 - 一个公有方法
getDepartment(),返回受保护的 department 值 - 一个公有方法
giveRaise(double amount),按给定金额增加 salary(仅当 amount 为正数时) - 一个公有方法
displayInfo(),按以下格式打印员工信息:"Name: <name>, Department: <department>, Salary: $<salary>"
- Public:员工的
main.cpp:通过与一个 Employee 对象交互,演示访问修饰符的作用。从输入中读取员工的姓名、部门和工资(分为三行),然后:- 使用输入值创建一个
Employee - 直接访问公有成员,打印员工姓名:
"Direct access - Name: <name>" - 使用 getter 打印部门:
"Via getter - Department: <department>" - 使用 getter 打印工资:
"Via getter - Salary: $<salary>" - 给员工加薪
5000.0 - 打印
"After raise:" - 调用
displayInfo()显示更新后的信息
- 使用输入值创建一个
使用 std::fixed 和 <iomanip> 中的 std::setprecision(2),将所有工资值格式化为两位小数。使用 std::stod() 将工资输入从字符串转换为 double。
这里的关键在于,虽然你可以在 main 中直接访问 name,但不能直接访问 department 或 salary。你必须使用公有 getter 方法。这就是封装的实际应用:类控制着如何访问和修改其中的数据。
亲手试试
#include <iostream>
#include <string>
#include <iomanip>
#include "Employee.h"
using namespace std;
int main() {
// 读取输入
string name;
string department;
string salaryStr;
getline(cin, name);
getline(cin, department);
getline(cin, salaryStr);
double salary = stod(salaryStr);
// 设置薪资输出的精度
cout << fixed << setprecision(2);
// TODO:使用输入值创建一个 Employee 对象
// TODO:直接访问公有成员,输出员工姓名
// 格式:"Direct access - Name: <name>"
// TODO:使用 getter 方法输出部门
// 格式:"Via getter - Department: <department>"
// TODO:使用 getter 方法输出薪资
// 格式:"Via getter - Salary: $<salary>"
// TODO:给员工加薪 5000.0
// TODO:输出 "After raise:"
// TODO:调用 displayInfo() 显示更新后的信息
return 0;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C++ 在线编译器