C++中子类使用公有保护私有继承父类的功能区别
·
C++ 公有、保护、私有继承的功能区别详解
在C++中,继承有三种访问限定符:public、protected和private。它们决定了父类成员在子类中的访问权限和对外暴露程度。
核心区别总结表
| 特性 | 公有继承 (public) | 保护继承 (protected) | 私有继承 (private) |
|---|---|---|---|
| 父类 public成员在子类中的访问权限 | public | protected | private |
| 父类protected成员在子类中的访问权限 | protected | protected | private |
| 外部代码访问继承的父类成员 | 可通过子类对象访问父类public成员 | 不可访问 | 不可访问 |
| 后续派生类访问父类成员 | 可访问父类public/protected成员 | 只能访问父类public/protected成员(转为protected) | 不可访问父类任何成员 |
语义含义 “是一个” (is-a) 关系 “是受限制的” 关系 “根据某物实现” (implemented-in-terms-of) 关系
使用频率 最常见(约95%场景) 极少使用 较少使用
详细代码示例
#include <iostream>
using namespace std;
class Base {
public:
int publicVar = 10;
void publicMethod() { cout << "Base public method" << endl; }
protected:
int protectedVar = 20;
void protectedMethod() { cout << "Base protected method" << endl; }
private:
int privateVar = 30;
void privateMethod() { cout << "Base private method" << endl; }
};
// ================= 公有继承 (public) =================
class PublicDerived : public Base {
public:
void accessBaseMembers() {
publicMethod(); // ✅ 可以访问父类public方法
protectedMethod(); // ✅ 可以访问父类protected方法
// privateMethod(); // ❌ 不能访问父类private方法
}
};
// ================= 保护继承 (protected) =================
class ProtectedDerived : protected Base {
public:
void accessBaseMembers() {
publicMethod(); // ✅ 可以访问(此时public成员变为protected)
protectedMethod(); // ✅ 可以访问
// privateMethod(); // ❌ 不能访问
}
};
// ================= 私有继承 (private) =================
class PrivateDerived : private Base {
public:
void accessBaseMembers() {
publicMethod(); // ✅ 可以访问(此时public成员变为private)
protectedMethod(); // ✅ 可以访问(此时protected成员变为private)
// privateMethod(); // ❌ 不能访问
}
};
// 测试函数
void testAccess() {
// ----------------- 公有继承测试 -----------------
PublicDerived pubDer;
pubDer.publicMethod(); // ✅ 外部可直接调用父类public方法
// pubDer.protectedMethod(); // ❌ 错误:protected成员外部不可访问
// ----------------- 保护继承测试 -----------------
ProtectedDerived protDer;
// protDer.publicMethod(); // ❌ 错误:继承后public成员变为protected,外部不可访问
// ----------------- 私有继承测试 -----------------
PrivateDerived privDer;
// privDer.publicMethod(); // ❌ 错误:继承后public成员变为private,外部不可访问
}
// ================= 多级继承测试 =================
class GrandchildPublic : public PublicDerived {
void access() {
publicMethod(); // ✅ 可访问(通过public继承保留)
protectedMethod(); // ✅ 可访问
}
};
class GrandchildProtected : public ProtectedDerived {
void access() {
publicMethod(); // ✅ 可访问(在ProtectedDerived中变为protected)
protectedMethod(); // ✅ 可访问
}
};
class GrandchildPrivate : public PrivateDerived {
void access() {
// publicMethod(); // ❌ 不可访问(在PrivateDerived中变为private)
// protectedMethod(); // ❌ 不可访问
}
};
int main() {
testAccess();
return 0;
}
关键点解析
-
公有继承 (public):
• 保持父类原有的访问权限
• 适用于"is-a"关系(例如:Dog继承自Animal)
• 父类接口完全暴露给子类用户 -
保护继承 (protected):
• 父类的public成员在子类中变为protected
• 父类的protected成员保持protected
• 主要用于限制接口暴露(使用场景极少) -
私有继承 (private):
• 父类的public和protected成员在子类中都变为private
• 表示"implemented-in-terms-of"关系(根据某物实现)
• 通常可用组合(composition)替代
最佳实践建议
- 优先使用公有继承:当需要表达"is-a"关系时(约95%的继承场景)
- 慎用私有继承:仅在需要重写虚函数或进行空基类优化时考虑
- 避免使用保护继承:实际项目中几乎总能用组合或公有继承替代
- 使用组合代替继承:当关系是"has-a"而非"is-a"时,优先选择包含对象成员
⚠️重要提示:无论使用何种继承方式,父类的private成员始终不可访问,只能通过父类提供的public/protected接口间接访问。*
更多推荐


所有评论(0)