C++ 类的继承:public、protected、private 访问控制
C++ 的类继承机制允许你基于已有类创建新类,并复用其代码。但继承时如何控制成员的可见性,直接决定了派生类能否访问基类的成员,也影响外部代码对派生类对象的操作权限。关键就在于继承方式(public、protected、private)与成员原始访问修饰符(public、protected、private)的组合效果。
理解三种访问修饰符的原始含义
在讨论继承前,先明确类内部三种访问修饰符的作用:
public成员:任何地方都能访问,包括类外代码、派生类。protected成员:仅当前类和其派生类可访问,类外代码不可见。private成员:只有定义它的类自身能访问,派生类和类外代码都不可见。
例如:
class Base {
public:
int pub = 1;
protected:
int pro = 2;
private:
int pri = 3;
};
- 在
main()中只能访问pub。 - 在派生类中可以访问
pub和pro,但不能访问pri。
继承方式如何改变成员的访问级别
当你用不同方式继承基类时,基类成员在派生类中的“新访问级别”会发生变化。规则如下:
public继承:基类成员的访问级别保持不变。protected继承:基类的public成员在派生类中变为protected;protected成员仍为protected;private成员依然不可见。private继承:基类的public和protected成员在派生类中都变为private;private成员依然不可见。
下面通过一个表格清晰展示所有组合结果:
| 基类成员原访问级别 | public 继承后在派生类中的访问级别 | protected 继承后在派生类中的访问级别 | private 继承后在派生类中的访问级别 |
|---|---|---|---|
| public | public | protected | private |
| protected | protected | protected | private |
| private | 不可见 | 不可见 | 不可见 |
注意:“不可见”意味着派生类无法直接使用该成员,无论继承方式如何。
实际代码演示三种继承方式
1. public 继承(最常用)
class Base {
public:
int pub = 1;
protected:
int pro = 2;
};
class DerivedPublic : public Base {
public:
void test() {
pub = 10; // ✅ 可访问
pro = 20; // ✅ 可访问
}
};
int main() {
DerivedPublic d;
d.pub = 100; // ✅ 外部可访问
// d.pro = 200; // ❌ 编译错误:pro 是 protected
}
2. protected 继承
class DerivedProtected : protected Base {
public:
void test() {
pub = 10; // ✅ 可访问(现在是 protected)
pro = 20; // ✅ 可访问
}
};
int main() {
DerivedProtected d;
// d.pub = 100; // ❌ 编译错误:pub 在派生类中是 protected
}
3. private 继承
class DerivedPrivate : private Base {
public:
void test() {
pub = 10; // ✅ 可访问(现在是 private)
pro = 20; // ✅ 可访问
}
};
int main() {
DerivedPrivate d;
// d.pub = 100; // ❌ 编译错误:pub 在派生类中是 private
}
如何选择继承方式?
绝大多数情况下,只使用 public 继承。因为:
- 它表达了“is-a”关系(例如,“狗 is-a 动物”),符合面向对象设计原则。
- 保持接口一致性,外部代码可以像使用基类一样使用派生类对象。
protected 或 private 继承通常用于实现细节复用,而非接口复用。例如,当你想复用某个类的功能,但不希望暴露其公共接口时,可用 private 继承(此时更推荐组合而非继承)。
特殊情况:using 声明提升访问级别
即使使用了 private 或 protected 继承,你仍可通过 using 声明在派生类中提升特定成员的访问级别:
class Derived : private Base {
public:
using Base::pub; // 将 pub 提升为 public
// pro 仍然是 private(不可提升,因原始为 protected)
};
int main() {
Derived d;
d.pub = 50; // ✅ 现在可以访问
}
注意:using 只能提升访问级别,不能降低;且不能用于基类的 private 成员(因为根本不可见)。
验证你的理解:快速自查
- 创建一个基类
A,包含public、protected、private成员各一个。 - 分别用
public、protected、private方式继承A,得到三个派生类。 - 在每个派生类的成员函数中尝试访问基类的三个成员,记录哪些能编译通过。
- 在 main 函数中尝试通过派生类对象访问
public成员,观察是否成功。
你会发现:只有 public 继承能让基类的 public 成员在派生类对象上依然可访问。其他继承方式都会限制外部访问,即使成员原本是 public。

暂无评论,快来抢沙发吧!