前面我们学习了类的基本用法,并在上篇C++57个入门知识点_27 继承的概念(类的组合关系:将一个类的对象作为另外一个类的成员;类的组合关系的访问;继承的概念:A类是B的儿子;A被称为子类,B被称为父类或者A被称为派生类,B被称为基类)中介绍了继承的基本概念。本篇将会介绍继承的可见性。
总结:
- 前面我们学习过
public
和private
关键字
-
public
: 公有,其声明的成员在类域的内部和外部都可以访问;
-
private
:私有,其声明的成员只能在类域的内部而不能在类域的外部访问;
-
保护成员(protected):保护成员除了自身或者派生类,不能在其他类使用(只有自己和儿子可以使用,其他不可以使用);
- 影响父类成员在子类中的可见性的关键字有两个地方:
一个是父类内部的关键字,一个是继承位置的关键字
。
-
继承的可见性:
父亲某个属性的成员,通过关键字变为儿子中某种属性成员
这个访问权限是在编译时期做的检查,实际子类的对象的内存中包含父类的所有成员
父类(CPerson) <-- 公有继承public -- 子类(CStudent)
公有成员(public) 公有成员(public)
保护成员(protected) 保护成员(protected)
私有成员(private) 不可见
父类(CPerson) <-- 公有继承protected -- 子类(CTeacher)
公有成员(public) 公有成员(protected)
保护成员(protected) 保护成员(protected)
私有成员(private) 不可见
父类(CPerson) <-- 公有继承private -- 子类(CTeacher)
公有成员(public) 私有成员(private)
保护成员(protected) 私有成员(private)
私有成员(private) 不可见
1. protected关键字
保护成员(protected)
:保护成员除了自身或者派生类,不能在其他类使用(只有自己和儿子可以使用,其他不可以使用)
- 类域外的访问属性:
protected
和private
在类域外部的效果是一样的。
以下代码:CPerson
类中定义了一个protected
关键字的成员,在类域外对其进行访问
class CPerson
{
public:
CPerson() {
}
~CPerson() {
}
int GetGender() {
return m_nGender;
}
void SetGender(int nGender) {
m_nGender = nGender;
}
public:
int m_nPublic;
protected:
int m_nProtected;
private:
char m_nszName[255];
int m_nGender;
int m_nPrivate;
};
class CStudent : public CPerson
{
public:
CStudent() {
}
~CStudent() {
}
private:
int m_nStuID;
};
int main(int argc, char* argv[])
{
CPerson per;
per.m_nProtected = 1;
return 0;
}
运行结果:显示该成员无法访问
对于private
关键字下的int m_nPrivate
也是一样的,使用CPerson per; per.m_nPrivate = 1;
也是无法访问的
对于public
关键字下的int m_nPublic;
是可以用CPerson per; per.m_nPublic = 1;
进行访问的。
- 子类继承中的可见性:对于
CPerson
采用public
继承的子类CStudent
,其对象访问CPerson
中public
、protected
和private
下的成员也是与上面结果一样。
2. 子类类域内部对父类成员的可见性
//父亲公有的都可以访问
public :
int m_nPublic;
//父亲的家族财产给儿子继承
protected:
int m_nProtected;
//父亲的私有财产不能给儿子继承
private:
char m_nszName[255];
int m_nGender;
在CStudent
类的内部访问CPerson
的成员:
#include <iostream>
class CPerson
{
public:
CPerson() {
}
~CPerson() {
}
int GetGender() {
return m_nGender;
}
void SetGender(int nGender) {
m_nGender = nGender;
}
public:
int m_nPublic;
protected:
int m_nProtected;
private:
char m_nszName[255];
int m_nGender;
int m_nPrivate;
};
class CStudent : public CPerson
{
public:
CStudent() {
m_nPublic = 1;
m_nProtected = 1;
m_nPrivate = 1;
}
~CStudent() {
}
private:
int m_nStuID;
};
int main(int argc, char* argv[])
{
CPerson per;
CStudent stu;
return 0;
}
运行结果:CStudent
中可以访问CPerson
中的public
和protected
成员,但是不能访问private
从上面的结果可以看到,父类中的成员对于子类是具有一定的可见性的,即父类中的不是所有成员都是可以被子类继承,有些可继承有些不可以,这些都是取决于关键字
。
除了CPerson
内部的关键字,可以看到CStudent
继承 CPerson
的地方也是可以看到关键字,class CStudent : public CPerson {...}
因此影响父类成员在子类中的可见性的关键字有两个地方,一个是父类内部的关键字,一个是继承位置的关键字
。
3. 父类成员在子类中的可见性
-
关键点:
两个权限取在一起,取最严格的
-
继承的可见性:
父亲某个属性的成员,通过关键字变为儿子中某种属性成员
这个访问权限是在编译时期做的检查,实际子类的对象的内存中包含父类的所有成员
父类(CPerson) <-- 公有继承public -- 子类(CStudent)
公有成员(public) 公有成员(public)
保护成员(protected) 保护成员(protected)
私有成员(private) 不可见
父类(CPerson) <-- 公有继承protected -- 子类(CTeacher)
公有成员(public) 公有成员(protected)
保护成员(protected) 保护成员(protected)
私有成员(private) 不可见
父类(CPerson) <-- 公有继承private -- 子类(CTeacher)
公有成员(public) 私有成员(private)
保护成员(protected) 私有成员(private)
私有成员(private) 不可见
以下代码中:CStudent
类私有继承CPerson
类 class CStudent : private CPerson
,查看父类成员在子类中的可见性
#include <iostream>
class CPerson
{
public:
CPerson() {
}
~CPerson() {
}
int GetGender() {
return m_nGender;
}
void SetGender(int nGender) {
m_nGender = nGender;
}
public:
int m_nPublic;
protected:
int m_nProtected;
private:
char m_nszName[255];
int m_nGender;
int m_nPrivate;
};
class CStudent : private CPerson
{
public:
CStudent() {
m_nPublic = 1;
m_nProtected = 1;
//m_nPrivate = 1;
}
~CStudent() {
}
private:
int m_nStuID;
};
class CTeacher : public CPerson
{
public:
CTeacher() {
}
~CTeacher() {
}
private:
int m_nTeaID;
};
int main(int argc, char* argv[])
{
CStudent stu;
stu.m_nPublic = 1;
stu.m_nProtected = 1;
return 0;
}
运行结果:
4.学习视频:C++57个入门知识点_28 继承的可见性
5.学习笔记:
#include <iostream>
//面向对象:继承
//public: 公有
//protected: 保护
//private:私有
//继承的可见性:
/*
保护成员(protected):保护成员除了自身或者派生类以外,不能在其他类使用
这个访问权限是在编译时期做的检查,实际子类的对象的内存中包含父类的所有成员
两个权限取在一起,取最严格的
父类(CPerson) <-- 公有继承public -- 子类(CStudent)
公有成员(public) 公有成员(public)
保护成员(protected) 保护成员(protected)
私有成员(private) 不可见
父类(CPerson) <-- 公有继承protected -- 子类(CTeacher)
公有成员(public) 公有成员(protected)
保护成员(protected) 保护成员(protected)
私有成员(private) 不可见
父类(CPerson) <-- 公有继承private -- 子类(CTeacher)
公有成员(public) 私有成员(private)
保护成员(protected) 私有成员(private)
私有成员(private) 不可见
*/
class CPerson
{
public:
CPerson() {
}
~CPerson() {
}
int GetGender() {
return m_nGender;
}
void SetGender(int nGender) {
m_nGender = nGender;
}
//父亲公有的都可以访问
public :
int m_nPublic;
//父亲的家族财产给儿子继承
protected:
int m_nProtected;
//父亲的私有财产不能给儿子继承
private:
char m_nszName[255];
int m_nGender;
};
//父类的继承也有三种属性
class CStudent :public CPerson
{
public:
CStudent(){
m_nPublic = 1;
m_nProtected = 1;//类域内部可以访问父类的保护成员
}
~CStudent() {
}
private:
int m_nStuID;
};
//增加老师管理系统,老师的数据与行为和学生是类似的,但也有学号,老师号的不同
//如果重建一个老师类就会造成冗余,易造成错误
class CTeacher :public CPerson
{
public:
CTeacher() {
}
~CTeacher() {
}
private:
int m_nTeaID;
};
int main(int argc,char* argv[])
{
CPerson per;
per.m_nPublic = 1;
CStudent stu;
return 0;
}