C++类成员的访问权限及继承方式(public,protected,private)

1、访问权限

C++通过 public、protected、private 三个关键字来控制成员变量和成员函数的访问权限,它们分别表示公有的、受保护的、私有的,被称为成员访问限定符。所谓访问权限,就是你能不能使用该类中的成员。

在类的内部(定义类的代码内部),无论成员被声明为 public、protected 还是 private,都是可以互相访问的,没有访问权限的限制。

在类的外部(定义类的代码之外),只能通过对象访问成员,并且通过对象只能访问 public 属性的成员,不能访问 private、protected 属性的成员。

类成员的访问权限由高到低依次为 public --> protected --> private。

2、继承方式

public、protected、private 指定继承方式

不同的继承方式会影响基类成员在派生类中的访问权限。
1) public继承方式

  • 基类中所有 public 成员在派生类中为 public 属性;
  • 基类中所有 protected 成员在派生类中为 protected 属性;
  • 基类中所有 private 成员在派生类中不能使用。

2) protected继承方式

  • 基类中的所有 public 成员在派生类中为 protected 属性;
  • 基类中的所有 protected 成员在派生类中为 protected 属性;
  • 基类中的所有 private 成员在派生类中不能使用。

3) private继承方式

    • 基类中的所有 public 成员在派生类中均为 private 属性;
    • 基类中的所有 protected 成员在派生类中均为 private 属性;
    • 基类中的所有 private 成员在派生类中不能使用。

C++继承的一般语法为:

class 派生类名:[继承方式] 基类名{
    派生类新增加的成员
};

 

下面用多级继承的例子来说明public、protected、private的关系,如下:

 1 #include<iostream>
 2 using namespace std;
 3 //基类People
 4 class People{
 5 public:
 6     void setname(char *name);
 7     void setage(int age);
 8     void sethobby(char *hobby);
 9     char *gethobby();
10 protected:
11     char *m_name;
12     int m_age;
13 private:
14     char *m_hobby;
15 };
16 void People::setname(char *name){ m_name = name; }
17 void People::setage(int age){ m_age = age; }
18 void People::sethobby(char *hobby){ m_hobby = hobby; }
19 char *People::gethobby(){ return m_hobby; }
20 //派生类Student
21 class Student: public People{
22 public:
23     void setscore(float score);
24 protected:
25     float m_score;
26 };
27 void Student::setscore(float score){ m_score = score; }
28 //派生类Pupil
29 class Pupil: public Student{
30 public:
31     void setranking(int ranking);
32     void display();  //显示输出函数
33 private:
34     int m_ranking;
35 };
36 void Pupil::setranking(int ranking){ m_ranking = ranking; }
37 void Pupil::display(){
38     cout<<m_name<<"的年龄是"<<m_age<<",考试成绩为"<<m_score<<"分,班级排名第"<<m_ranking<<",TA喜欢"<<gethobby()<<""<<endl;
39 }
40 int main(){
41     Pupil pup;
42     pup.setname("小明");
43     pup.setage(15);
44     pup.setscore(92.5f);
45     pup.setranking(4);
46     pup.sethobby("乒乓球");
47     pup.display();
48     return 0;
49 }

运行结果:

小明的年龄是15,考试成绩为92.5分,班级排名第4,TA喜欢乒乓球。

这是一个多级继承的例子,Student 继承自 People,Pupil 又继承自 Student,它们的继承关系为 People --> Student --> Pupil。Pupil 是最终的派生类,它拥有基类的 m_name、m_age、m_score、m_hobby 成员变量以及 setname()、setage()、sethobby()、gethobby()、setscore() 成员函数。

注意,在派生类 Pupil 的成员函数 display() 中,我们借助基类的 public 成员函数 gethobby() 来访问基类的 private 成员变量 m_bobby,因为 m_hobby 是 private 属性的,在派生类中不可见,所以只能借助基类的 public 成员函数 sethobby()、gethobby() 来访问。

在派生类中访问基类 private 成员的唯一方法就是借助基类的非 private 成员函数,如果基类没有非 private 成员函数,那么该成员在派生类中将无法访问。

3、改变访问权限

使用 using 关键字可以改变基类成员在派生类中的访问权限,例如将 public 改为 private、将 protected 改为 public。

注意:using 只能改变基类中 public 和 protected 成员的访问权限,不能改变 private 成员的访问权限,因为基类中 private 成员在派生类中是不可见的,根本不能使用,所以基类中的 private 成员在派生类中无论如何都不能访问。

using 关键字使用示例:

 1 #include<iostream>
 2 using namespace std;
 3 //基类People
 4 class People {
 5 public:
 6 void show();
 7 protected:
 8 char *m_name;
 9 int m_age;
10 };
11 void People::show() {
12 cout << m_name << "的年龄是" << m_age << endl;
13 }
14 //派生类Student
15 class Student : public People {
16 public:
17 void learning();
18 public:
19 using People::m_name; //将protected改为public
20 using People::m_age; //将protected改为public
21 float m_score;
22 private:
23 using People::show; //将public改为private
24 };
25 void Student::learning() {
26 cout << "我是" << m_name << ",今年" << m_age << "岁,这次考了" << m_score << "分!" << endl;
27 }
28 int main() {
29 Student stu;
30 stu.m_name = "小明";
31 stu.m_age = 16;
32 stu.m_score = 99.5f;
33 //stu.show(); //因为 show() 函数是 private 属性的,所以代码会报错,把该行注释掉
34 stu.learning();
35 return 0;
36 }

程序输出结果为:

我是小明,今年16岁,这次考了99.5分!

代码中首先定义了基类 People,它包含两个 protected 属性的成员变量和一个 public 属性的成员函数。定义 Student 类时采用 public 继承方式,People 类中的成员在 Student 类中的访问权限默认是不变的。

不过,我们使用 using 改变了它们的默认访问权限,如代码第 19~23 行所示,将 show() 函数修改为 private 属性的,是降低访问权限,将 name、age 变量修改为 public 属性的,是提高访问权限。

 

posted @ 2019-08-08 16:45  秦沐  阅读(2495)  评论(0)    收藏  举报