在 C++ 中public、protected、private是 访问控制修饰符(Access Specifiers),用于限制类(class/struct)成员(属性、方法)的访问权限 —— 核心目的是实现封装性(隐藏内部实现细节,仅暴露必要接口),同时支持继承体系中的权限控制。
访问权限的核心规则:从类外部能否直接访问成员、子类能否访问父类的成员。
1. public(公有访问)
含义:类的公有成员是 “对外暴露的接口”,不受访问限制。
访问范围:
类的外部代码(如 main 函数、其他普通函数)可以直接访问;
类的成员函数(自身内部)可以访问;
类的子类(派生类)可以直接访问(无论哪种继承方式)。
使用场景:暴露给外部的接口(如构造函数、对外提供的功能方法、必要的公开属性)。
示例:
class Person {
public: // 公有成员
std::string name; // 公有属性
void sayHello() { // 公有方法
std::cout << "Hello, " << name << std::endl;
}
};
// 类外部访问 public 成员(允许)
int main() {
Person p;
p.name = "Alice"; // 直接访问公有属性
p.sayHello(); // 直接调用公有方法
return 0;
}
2. private(私有访问)
含义:类的私有成员是 “内部实现细节”,仅对类自身可见,完全隐藏对外。
访问范围:
仅允许类的自身成员函数(包括友元函数 / 友元类)访问;
类的外部代码无法直接访问(编译报错);
类的子类无法直接访问(即使是公有继承,子类也不能直接用父类的 private 成员)。
使用场景:隐藏内部状态或辅助方法(如内部缓存、私有工具函数),避免外部误修改。
示例:
class BankAccount {
private: // 私有成员(内部状态,对外隐藏)
double balance; // 账户余额(不允许外部直接修改)
public: // 公有接口(控制访问)
void deposit(double money) { // 存款(仅通过该接口修改余额)
if (money > 0) balance += money;
}
double getBalance() { // 查询余额(仅暴露读取接口)
return balance;
}
};
int main() {
BankAccount acc;
// acc.balance = 1000; // 错误:private 成员,外部无法直接访问
acc.deposit(1000); // 正确:通过公有接口修改
std::cout << acc.getBalance() << std::endl; // 正确:通过公有接口读取
return 0;
}
3. protected(受保护访问)
含义:类的受保护成员是 “仅对自身和子类可见的内部成员”,介于 public 和 private 之间。
访问范围:
允许类的自身成员函数访问;
允许类的子类(派生类)的成员函数直接访问(无论哪种继承方式);
类的外部代码无法直接访问(编译报错)。
使用场景:父类希望子类继承并使用,但不希望外部代码访问的成员(如父类的辅助方法、子类需要复用的属性)。
示例:
class Animal {
protected: // 受保护成员(子类可访问,外部不可)
std::string species; // 物种(子类需要用到,但外部无需知道)
public:
Animal(std::string s) : species(s) {}
};
// 子类 Dog 继承 Animal
class Dog : public Animal {
public:
Dog() : Animal("Dog") {}
void showSpecies() {
// 正确:子类成员函数可直接访问父类的 protected 成员
std::cout << "I am a " << species << std::endl;
}
};
int main() {
Dog dog;
dog.showSpecies(); // 正确:通过子类公有接口间接访问
// std::cout << dog.species << std::endl; // 错误:外部无法访问 protected 成员
return 0;
}
关键补充:继承中的权限变化
当子类继承父类时(public/protected/private 继承),父类成员在子类中的 “可见性” 会有变化,但核心规则不变:子类永远无法访问父类的 private 成员。
注:struct 与 class 的默认访问权限不同:
class:默认成员权限为 private,默认继承方式为 private;
struct:默认成员权限为 public,默认继承方式为 public(兼容性设计,与 C 语言一致)。
总结:核心区别表
一句话记忆:public 对外,private 对内,protected 父对子开放、对外封闭。
end