类的成员的访问控制
类的定义形式中指出,描述成员需要使用相应的访问限定符,在例2-1中也看到Car类中的成员函数都具有public属性,数据成员都具有private属性。public、private的具体含义是什么,还有没有其他的访问限定符?学习了本节内容,这些疑问都将得到解答。
访问限定符声明了类中各个成员的访问权限。C++中可用的访问限定符有:public、protected、private三个。下面对三种访问限定符的属性进行说明。
1、访问限定符public
被public修饰的成员也称为公有成员,具有与类外交互的能力,可以被该类的其他成员函数及类外的其他函数使用。
2、 访问限定符private
被private修饰的成员称为私有成员,只能由类中的函数访问,不可通过该类的对象进行访问。
之所以引入private是因为在面向对象思想中最重要的一个特点就是封装,类中的成员不应该被随意更改,防止成员存入一个不合理的数值,数据操作都应该在可控范围之内。
比如,我们编写一个描述人的类,其中有表示年龄的属性int m_nAge,该属性如果设定为public属性,那么在类的外部就可以随意通过类对象设置m_nAge值,m_nAge设置为1000时显然与实际情况不相符,那么我们就应该防止这种不合理操作,将m_nAge属性的访问说明符设置为private,将对该属性的操作限定在类对应的成员函数中,实现对数据的封装和保护。
3、 访问限定符protected
被protected修饰的成员称为保护成员,其访问权限介于私有和公有之间,本类的成员和该类的派生类可以访问,类外的其他函数不可以访问。
若没有指定成员的访问权限,通过class关键字定义的类中成员默认具有private属性,通过struct关键字定义的类中成员默认具有public属性。一般情况下,三种访问限定符可以按任意次序出现,但通常将公有成员排列在类的前部。
三个访问限定符的作用权限如表1的所示。
表1 类的访问限定符
访问限定符 | 属性说明 | 本类 | 派生类 | 其他 |
---|---|---|---|---|
public | 公有成员 | Yes | Yes | Yes |
protected | 保护成员 | Yes | Yes | No |
private | 私有成员 | Yes | No | No |
接下来使用不同的访问限定符修饰不同的成员,观察其操作方面的区别,如例1所示。
1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 class Car //定义汽车类
6 {
7 public:
8 void set_carname(string newname) //设置汽车名称的成员函数
9 {
10 m_strCarName = newname;
11 }
12 string get_carname() //获取汽车名称的成员函数
13 {
14 return m_strCarName;
15 }
16 void display_welcomemsg() //显示欢迎信息的成员函数
17 {
18 cout << "Welcome to the car world for " << m_strCarName << "!" << endl;
19 }
20 private:
21 string m_strCarName;
22 };
23
24 int main()
25 {
26 string new_carname; //定义变量用于保存用户输入的汽车名称
27 Car mycar;
28
29 cout << "enter the car name : ";
30 getline(cin, new_carname); //使用getline()函数读取一个字符串
31 mycar.set_carname(new_carname); //调用函数设置汽车名称
32 mycar.display_welcomemsg(); //显示欢迎信息
33
34 system("pause");
35 return 0;
36 }
运行结果如图1所示。
图1 例1运行结果
对于本例,我们分为两部分进行分析。
1、在此例中从第5行到22行是类的定义,类中三个成员函数display_welcomemsg()、
set_carname()、get_carname()都具有public属性,后面的两个函数用于设置和获取汽车名称,另
外类中还有一个数据成员m_strCarName,具有private属性。在C++中可以使用private实现成
员的私有化,m_strCarName成员的设置和修改只能通过类内部的成员函数实现,本例中通过
set_carname()对汽车名称进行设置,get_carname()获取汽车名称。
2、在main()函数中首先定义类对象mycar和普通的string变量new_carname,然后从键盘读取汽车名称对mycar对象中的m_strCarName属性进行设置,因为该成员是具有private属性,因此对该成员的设置需要借助于set_carname()成员函数,这样就实现了私有成员和外部数据的交互。类中的m_strCarName成员不可在类外通过对象名访问,若main()函数中出现下列语句:
mycar.m_strCarName = new_carname;
编译时提示:“Car::m_strCarName”: 无法访问 private 成员(在“Car”类中声明)”的错误。