详解C++中的公有继承与私有继承访问规则
在C++面向对象编程中,继承是实现代码复用和多态的核心机制。根据声明方式的不同,继承关系主要分为公有继承(public)和私有继承(private)。理解两者对基类成员(public、protected、private)在派生类中访问属性的影响,是编写正确C++程序的关键。
什么是私有继承及其访问规则
当在派生类声明中将基类的继承方式指定为 private 时,称为私有继承。由此建立的派生类称为私有派生类(private derived class)。
私有继承最显著的特征是“隐藏”。其基类(public base class)的所有非私有成员在派生类中均被视为 private。具体访问属性变化如下:

简而言之:
- 基类 public/protected 成员:在派生类中变成
private。这意味着派生类内部可以访问,但派生类外部(包括通过派生类对象)无法访问。 - 基类 private 成员:在派生类中成为不可访问的成员。仅能通过基类的成员函数间接访问。
由于私有继承将基类的接口彻底隐藏,下一层的派生类也无法访问其任何成员,因此在不需要继续向下继承的场景中,为了隐蔽功能逻辑时才会使用。但由于其访问限制较多,一般日常编程中使用较少。
第1步:定义私有继承类并测试访问权限
假设我们有一个基类 Student,现在以私有方式创建一个派生类 Student1,观察不同作用域的访问情况。
class Student1: private Student // 用私有继承方式声明派生类Student1
{
public:
void display_1() {
// 以下引用均为派生类内的私有成员,访问正确
cout<<"age: "<<age<<endl;
cout<<"address: "<<addr<<endl;
}
private:
int age;
string addr;
};
第2步:在主函数中验证非法访问
接下来编写主函数,尝试通过对象访问各类成员:
int main()
{
Student1 stud1; // 定义一个Student1类的对象
// 错误!stud1.display(); 编译报错
// 原因:私有基类的公用成员在派生类中是私有函数,不能由对象直接调用。
stud1.display_1(); // 正确,display_1是Student1的公用函数
// 错误!stud1.age = 18; 编译报错
// 原因:age属于私有基类的成员或派生类内部私有变量,外界不可引用。
return 0;
}
结论: 私有继承切断了从派生类对象到基类功能的直接路径。
第3步:如何在类内间接调用私有基类成员?
如果必须在类外输出基类信息(例如基类的 display 方法),虽然不能直接在 main 中调用基类方法,但可以通过派生类的成员函数来中转调用。因为基类的公用函数在派生类中变成了私有的,它仍然可以被派生类的其他成员函数调用。
修改派生类的成员函数 display_1:
void display_1() {
display(); // 在派生类内部调用基类的公用函数(此时它是派生类的私有函数,合法)
cout<<"age: "<<age<<endl;
cout<<"address: "<<addr<<endl;
}
此时的 main 函数非常简洁:
int main()
{
Student1 stud1;
stud1.display_1(); // 仅一行即可输出所有数据
return 0;
}
这种链式调用(外部调派生类公用函数 -> 派生类调基类公用函数 -> 基类访问基类私有成员)是处理私有继承时的标准技巧。
什么是公有继承及其封装意义
将基类的继承方式指定为 public 时,称为公有继承。这是最常用的继承方式,体现了“is-a”的关系。在公有继承下,基类的成员访问属性在派生类中基本保持一致:

- 基类 public 成员:在派生类中保持
public。派生类对象可以直接访问。 - 基类 protected 成员:在派生类中保持
protected。派生类可以访问,对象不可访问。 - 基类 private 成员:**无论何种继承,基类的私有成员永远对派生类不可见。** 它们是隐形的。
第1步:为什么公有继承也不能直接访问基类私有成员?
这是一个重要的软件工程原则。私有成员体现了数据的封装性。如果派生类能直接访问基类的私有成员,那么基类和派生类之间就没有界限了,基类的内部实现细节将被完全暴露给子类。这破坏了面向对象的封闭性,使得系统难以维护和调试。
第2步:正确处理公有继承中的数据访问
在基类 Student 中定义了 num, name, sex 三个私有成员,在派生类 Student1 中定义了 age, addr。
错误的做法(在派生类内部直接引用基类私有变量):
class Student1: public Student
{
public:
void display_1() {
// 以下操作全部报错,num/name/sex是基类的私有成员
cout<<" num: "<<num<<endl;
cout<<" name: "<<name<<endl;
cout<<" sex: "<<sex<<endl;
}
private:
int age;
string addr;
};
正确的做法(通过基类公用成员函数获取数据):
我们可以简化派生类 Student1,只负责打印自己的私有成员:
class Student1: public Student
{
public:
void display_1() {
cout<<" age: "<<age<<endl;
cout<<" address: "<<addr<<endl;
}
private:
int age;
string addr;
};
然后在 main 中分别调用基类和派生类的公用函数:
int main()
{
Student1 stud;
stud.display(); // 调用基类函数,输出3个基类数据
stud.display_1(); // 调用派生类函数,输出2个派生类数据
return 0;
}
进一步优化:在派生类的 display_1 中调用基类的 display,使主函数只需一行代码即可完成所有信息的输出。
以上就是C++类继承中公有与私有模式访问规则的详细内容,更多关于C++面向对象基础入门的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













