1.类成员的访问说明符

在C++语言中,访问说明符(access specifiers)被用来加强类的封装性。通过访问说明符,类的设计者可以规定哪些成员变量和成员函数是内部外部都可见的,哪些成员变量和成员函数是只能在类内部使用的,外部是不可见的。public说明符合private说明符就起了这样的区分作用。《C++ Primer》P240页写到:

  • 定义在public说明符之后的成员在整个程序内可以被访问,public成员定义类的接口。
  • 定义在private说明符之后的成员可以被类的成员函数访问,但是不能被使用该类的代码访问,private部分封装了(即隐藏)类的实现细节。

简单一点说,public和private的区别就在于是否可以通过实例化的类,也就是对象来访问。

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Sales_data{
 6 public:
 7     Sales_data() =default;
 8     Sales_data(const std::string&s,unsigned n ,double p):
 9             bookNo(s),units_sold(n),revenue(p*n){}
10     Sales_data(const std::string &s):bookNo(s){}
11     Sales_data(std::istream&);
12     std::string isbn()const{return bookNo;}
13     Sales_data &combine(const Sales_data&);
14 
15 private:
16     double avg_price()const
17     { return units_sold?revenue/units_sold:0;}
18     std::string bookNo;
19     unsigned units_sold = 0;
20     double revenue = 0.0;
21 };
22 int main()
23 {
24     Sales_data data1("123434");
25     cout<<data1.isbn()<<endl;  //正确:isbn是public的,可以被该类的代码访问
26     cout<<data1.bookNo<<endl; // 错误:bookNo是私有属性,不能被使用该类的代码(该类的对象访问)
27     return 0;
28 }

一般在面向对象中,方法总是public的,因为方法相当于接口,用户要使用接口实现功能呢;变量总是私有的,这样可以避免用户对类进行修改。

友元:

如果其他类或者函数需要访问它的非公有成员, 那就要让这些类和函数成为它的友元(friend)。具体做法是在类内部添加一条以friend关键字开头的函数声明语句:

1 class Sales_data{
2 friend Sales_data add(const Sales_data&,const Sales_data&);
3 ...
4 };
5 
6 Sales_data add(const Sales_data&,const Sales_data&); //友元函数在类的外部声明和定义

友元函数不能被继承和传递。

 

protected访问说明符:

再引入继承的概念之后,我们希望类的一些属性可以被子类访问,但是还是不能被公共访问,这时候要用到protected访问说明符。

  • 和私有成员类似,受保护的成员对于类的用户来说是不可访问的。
  • 和公有成员类似,受保护的成员对于派生类的成员和友元来说是可访问的。
  • 派生类的成员或友元只能通过派生类对象来访问基类的受保护成员。派生类对于一个基类对象中的受保护成员没有任何访问权限。

 

访问控制和继承

派生类对其基类成员的访问权限受到两方面的影响,一是基类中成员的访问说明符,二是派生类列表中的访问说明符。其中,基类成员的访问说明符影响派生类内部的成员函数(新增)对基类成员的访问权限,派生类列表的访问说明符影响派生类对象对基类成员的访问。

1. 基类中成员的访问说明符

基类成员中的访问说明符影响派生类成员的访问权限

public成员:可以被派生类访问

protected成员:可以被派生类访问

private成员:不可以被派生类访问

2. 派生类列表中的访问说明符

派生类说明符对于派生类的成员函数(及友元)能否访问其直接基类的成员没有影响,它控制的是派生类用户(对象)对基类成员的访问。

public继承:基类的共有成员和保护成员作为派生类成员时,保持原有状态。

protected继承:基类的所有公有成员和私有成员都成为派生类的保护成员,只能被它的派生类成员和友元函数访问。

private继承:基类的所有公有成员和保护成员都作为派生类的私有成员,不能被它的派生类的派生类访问,即只能由派生类本身访问。

 

总结

基类成员 public protected private public protected private public protected private
继承方式 public protected private
派生类内部 public protected 不可见 protected protected  不可见 private private 不可见
派生类外部 可见 不可见 不可见 不可见 不可见  不可见 不可见 不可见 不可见