跳转至

3.2 访问控制与安装

我们使用 访问说明符(access specifiers) 加强类的封装性:

  • 定义在 public 说明符之后的成员在整个程序内可被访问,public成员定义类的接口
  • 定义在 private 说明符之后的成员可以被类的成员函数访问,但是不能被使用该类的代码访问,private部分封装(即隐藏)了类的实现细节。
class Sales_data {
    public:
        // 添加了访问说明符
        Sales_data() = default;
        Sales_data(const std::string &s, unsigned n, double p) :
            bookNo(s), units_sold(n), revenue(p*n) { }
        Sales_data(const std::string &s) : bookNo(s) { }
        Sales_data(std::istream&);
        std::string isbn() const { return bookNo; }
        Sales_data &combine(const Sales_data&);

    private:
        // 添加了访问说明符
        double avg_price() const
        { return units_sold ? revenue/units_sold : 0; }
        std::string bookNo;
        unsigned units_sold = 0;
        double revenue = 0.0;
};

一个类可以包含0个或多个访问说明符,而且对于某个访问说明符能出现多少次也没有严格限定。每个访问说明符指定了接下来的成员的访问级别,其有效范围直到出现下一个访问说明符或到达类的结尾处为止。

使用classstruct关键字

二者的唯一区别是,structclass的默认访问权限不太一样。

类可以在它的第一个说明符之前定义成员,若是struct则定义在第一个说明符之前的成员是public的;若是class,反之。

3.2.1 友元

class Sales_data {
    // 为 Sales_data的非成员函数所做的友元声明
    friend Sales_data add(const Sales_data&, const Sales_data&);
    friend std::istream& read(std::istream&, Sales_data&);
    friend std::ostream& print(std::ostream&, const Sales_data&);
    // 其他成员及访问说明符与之前一致
    public:
        // 添加了访问说明符
        Sales_data() = default;
        Sales_data(const std::string &s, unsigned n, double p) :
            bookNo(s), units_sold(n), revenue(p*n) { }
        Sales_data(const std::string &s) : bookNo(s) { }
        Sales_data(std::istream&);
        std::string isbn() const { return bookNo; }
        Sales_data &combine(const Sales_data&);
    private:
        // 添加了访问说明符
        double avg_price() const
        { return units_sold ? revenue/units_sold : 0; }
        std::string bookNo;
        unsigned units_sold = 0;
        double revenue = 0.0;
};

// Sales_data接口的非成员组成部分的声明
Sales_data add(const Sales_data&, const Sales_data&);
std::istream& read(std::istream&, Sales_data&);
std::ostream& print(std::ostream&, const Sales_data&);

类允许其他类或者函数访问它的非公有成员,方法是令其他类或者函数成为它的 友元(friend)。如果类想把一个函数作为它的友元,只需要增加一条以 friend 关键字开始的函数声明语句即可。

友元声明只能出现在类定义的任何地方,友元不是类的成员也不受它躲在区域访问控制级别的约束。

友元的声明:

友元的声明仅仅指定了访问的权限,我们必须在友元声明之外再专门对函数进行一次声明。

为了使友元对类的用户可见,我们通常把友元的声明与类本身放置在同一个头文件中(类的外部)。