ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

7-2 访问控制与封装

2022-02-20 08:31:49  阅读:195  来源: 互联网

标签:友元 封装 函数 访问控制 Sale istream data friend


目录

7.2.0 目标代码

#include<iostream>
using namespace std;
class Sale_data{
//为Sale_data的非成员函数所做的友元声明
friend istream &read (istream &, Sale_data &);
friend ostream &print(ostream &, Sale_data &);

public : //后面跟接口
    Sale_data() = default;
    Sale_data (string s) : bookNo(s) {}
    Sale_data(string s, unsigned n, double p) : 
              bookNo(s), units_sold(n), revenue(n*p) {}
    Sale_data(istream &);
    string ibsn() const {return bookNo;}
    Sale_data& combine(Sale_data& );
private : 
    double avg_price() const;
    //数据成员
    string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};

7.2.1 访问说明符

在c++语言中,我们使用访问说明符(access specifiers)加强类的封装性

  • 定义在public说明符之后的成员:在整个程序内可被访问, public成员定义类的接口。
  • 定义在private说明符之后的成员:可以被类的成员函数访问,但是不能被使用该类的代码访问,private部分封装了(即隐藏了)类的实现细节。
  • 一个类可以包含0或多个访问说明符,对于某一个访问说明符的数量也没有限制
  • 每个访问说明符的作用到下一个访问说明符之前或结尾

7.2.2 class 和 struct

使用class和struct定义类唯一的区别就是默认的访问权限。

  • class : 默认 private
  • struct : 默认 public

7.2.3 类的构成与友元

类的构成图

类的结构图

image-20220130215129167

友元

在类的外部,非成员的接口函数无法访问 private 的函数成员,而它又是接口函数,需要像其他接口函数一样能够访问类的非公有成员,那么如何解决此冲突呢? 在类中声明友元

类可以允许其他类或者函数访问它的非公有成员,方法是令其他类或者函数成为它的友元

声明友元: friend关键字

class Sale_data{
//为Sale_data的非成员函数所做的友元声明
friend istream &read (istream &, Sale_data &);
friend ostream &print(ostream &, Sale_data &);

//其他与之前一致
/*
  . . .
  . . .
*/

友元类以及友元成员函数

windows,screen是两个类,windows类有一个成员函clear,作用是情况指定screen类的内容。要达成注意功能

  • 将windows声明为screen的友元类,windows可以访问screen中的所有成员,包括非公有成员

    class screen{
        friend class windows;
        /*
        	. . .
        */
    }
    
  • 将clear函数声明为screen的友元函数

    class screen{
        //clear已经声明
        friend void windows::clear(screen &);
    }
    
  • 声明友元函数时需要注意声明顺序

    • 先定义windows类,声明clear函数,但不能定义它。
    • 定义screen类,声明clear为它的友元
    • 定义clear函数

关于友元声明的几个注意点

  • 友元声明只表示访问权限,不能代替函数声明。如在类Sale_data类内部中对print进行了友元声明,但是如果要使用print函数的话仍需要独立声明print函数

    struct x {
    	friend void f() {/*友元函数可以直接定义在内部*/};
    	x() {f();}  //错误,f()没有被声明
    	void h();
    	void g();
    };
    void x::h(); //错误:f()没有被声明
    void f();
    void x::g() {return f();}  //正确
    
  • 友元不具有传递性,某一个类的友元之间不互为友元

完整代码2

#include<iostream>
using namespace std;
class Sale_data{
friend istream &read (istream &, Sale_data &);
friend ostream &print(ostream &, Sale_data &);
public :
    //构造函数
    Sale_data() = default;
    Sale_data (string s) : bookNo(s) {}
    Sale_data(string s, unsigned n, double p) : 
              bookNo(s), units_sold(n), revenue(n*p) {}
    Sale_data(istream &);
    //关于Sale_data对象的操作函数
    string ibsn() const {return bookNo;}
    Sale_data& combine(Sale_data& );
private : 
    double avg_price() const;
    //数据成员
    string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};
//非成员函数接口
istream &read (istream &, Sale_data &);
ostream &print(ostream &, Sale_data &);
//外部构造函数
Sale_data::Sale_data(istream &is){
    read(is, *this);
}

istream &read(istream &is, Sale_data &item){
    double price = 0;
    is >> item.bookNo >>item.units_sold >> price;
    item.revenue = price * item.units_sold;
    return is;
}
ostream &print(ostream &os, Sale_data &item){
    os << item.bookNo << " " << item.units_sold << " "
       << item.revenue<<endl;
    return os;
}
//外部成员函数
Sale_data& Sale_data::combine(constSale_data& trans){
    units_sold += trans.units_sold;
    revenue += trans.revenue;
    return *this;
}
double Sale_data::avg_price() const{
    if(units_sold != 0)
        return revenue/units_sold;
    else
        return 0;
}

int main(){
    Sale_data item(cin);
    print(cout, item);
    return 0;
}

标签:友元,封装,函数,访问控制,Sale,istream,data,friend
来源: https://www.cnblogs.com/timothy020/p/15914813.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有