zoukankan      html  css  js  c++  java
  • 【c++ primer, 5e】访问控制与封装

    练习

    7.16

    无,类的接口定义在public说明符之后,类的实现细节定义在private说明符之后。

    7.17

    有。类成员的默认访问权限不同。class的类成员默认为private,struct的则默认为public。

    通常来说,当我们希望定义的类的所有成员是public的时候就用struct。

    7.18

    p242

    7.19

    【友元】

    练习

    7.20

    声明的类外函数需要直接引用类内的私有成员的时候要用到友元函数。

    设计原因:并非所有的、与某个类相关的函数都适合声明成那个类的成员函数,例如书上的add(obj, obj);

    利弊:不详。。。

    7.21

    遇到问题了。已经声明成友元函数还是不能访问私有数据???

    #include <iostream>
    #include <string>
    using namespace std;
    
    // Sales_data.h
    class Sales_data {
    friend Sales_data add(const Sales_data&, const Sales_data&);
    friend ostream &print(ostream&, const Sales_data&);
    friend istream &read(iostream&, Sales_data&);
    public:
        Sales_data() = default; 
        Sales_data(const string &s): bookNo(s) {} 
        Sales_data(const string &s, unsigned n, double p): bookNo(s), units_sold(n), revenue(p*n) {}
        Sales_data(istream&);
        std::string isbn() const { return bookNo; } 
        Sales_data& combine(const Sales_data&);
        double avg_price() const;
    private:
        string bookNo;
        unsigned units_sold = 0;
        double revenue = 0.0;
    };
    // Sales_data的非成员接口函数
    Sales_data add(const Sales_data&, const Sales_data&);
    ostream &print(ostream&, const Sales_data&);
    istream &read(iostream&, Sales_data&);
    
    // Sales_data.cpp
    Sales_data& Sales_data::combine(const Sales_data &rhs)
    {
        units_sold += rhs.units_sold;
        revenue += rhs.revenue;
        return *this;
    }
    istream &read(istream &is, Sales_data &item)
    {
        double price = 0;
        is >> item.bookNo >> item.units_sold >> price;
        item.revenue = price * item.units_sold;
        return is;
    }
    ostream &print(ostream &os, const Sales_data &item)
    {
        os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
        return os;
    }
    double Sales_data::avg_price() const {
        if (units_sold)
            return revenue/units_sold;
        else
            return 0;
    }
    Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
    {
        Sales_data sum = lhs;
        sum.combine(rhs);
        return sum;
    }
    Sales_data::Sales_data(istream &is)
    {
        read(is, *this);
    }
    
    
    // main.cpp
    int main()
    {
        Sales_data data1; // default
        Sales_data data2("ISOD233");
        Sales_data data3("ISOD233", 3, 22.5);
        Sales_data data4(cin);
        
        print(cout, data1) << endl;
        print(cout, data2) << endl;
        print(cout, data3) << endl;
        print(cout, data4) << endl;
        /* output:
        0 0
        ISOD233 0 0 0
        ISOD233 3 67.5 22.5
        DASD23 4 88 22
        */
        return 0;
    }

    编译结果如下:

    $ g++ prog1.cpp -std=c++11
    prog1.cpp: In function 'std::istream& read(std::istream&, Sales_data&)':
    prog1.cpp:19:12: error: 'std::__cxx11::string Sales_data::bookNo' is private
         string bookNo;
                ^
    prog1.cpp:38:16: error: within this context
         is >> item.bookNo >> item.units_sold >> price;
                    ^
    prog1.cpp:20:27: error: 'unsigned int Sales_data::units_sold' is private
         unsigned units_sold = 0;
                               ^
    prog1.cpp:38:31: error: within this context
         is >> item.bookNo >> item.units_sold >> price;
                                   ^
    prog1.cpp:21:22: error: 'double Sales_data::revenue' is private
         double revenue = 0.0;
                          ^
    prog1.cpp:39:10: error: within this context
         item.revenue = price * item.units_sold;
              ^
    prog1.cpp:20:27: error: 'unsigned int Sales_data::units_sold' is private
         unsigned units_sold = 0;
                               ^
    prog1.cpp:39:33: error: within this context
         item.revenue = price * item.units_sold;

     已改正:

    #include <iostream>
    #include <string>
    using namespace std;
    
    // Sales_data.h
    class Sales_data {
    friend Sales_data add(const Sales_data&, const Sales_data&);
    friend ostream &print(ostream&, const Sales_data&);
    friend istream &read(istream&, Sales_data&);
    public:
        Sales_data() = default; 
        Sales_data(const string &s): bookNo(s) {} 
        Sales_data(const string &s, unsigned n, double p): bookNo(s), units_sold(n), revenue(p*n) {}
        Sales_data(istream&);
        std::string isbn() const { return bookNo; } 
        Sales_data& combine(const Sales_data&);
        double avg_price() const;
    private:
        string bookNo;
        unsigned units_sold = 0;
        double revenue = 0.0;
    };
    // Sales_data的非成员接口函数
    Sales_data add(const Sales_data&, const Sales_data&);
    ostream &print(ostream&, const Sales_data&);
    istream &read(istream&, Sales_data&);
    
    // Sales_data.cpp
    Sales_data& Sales_data::combine(const Sales_data &rhs)
    {
        units_sold += rhs.units_sold;
        revenue += rhs.revenue;
        return *this;
    }
    istream &read(istream &is, Sales_data &item)
    {
        double price = 0;
        is >> item.bookNo >> item.units_sold >> price;
        item.revenue = price * item.units_sold;
        return is;
    }
    ostream &print(ostream &os, const Sales_data &item)
    {
        os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
        return os;
    }
    double Sales_data::avg_price() const {
        if (units_sold)
            return revenue/units_sold;
        else
            return 0;
    }
    Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
    {
        Sales_data sum = lhs;
        sum.combine(rhs);
        return sum;
    }
    Sales_data::Sales_data(istream &is)
    {
        read(is, *this);
    }
    
    
    // main.cpp
    int main()
    {
        Sales_data data1; // default
        Sales_data data2("ISOD233");
        Sales_data data3("ISOD233", 3, 22.5);
        Sales_data data4(cin);
        
        print(cout, data1) << endl;
        print(cout, data2) << endl;
        print(cout, data3) << endl;
        print(cout, data4) << endl;
        /* output:
        0 0
        ISOD233 0 0 0
        ISOD233 3 67.5 22.5
        DASD23 4 88 22
        */
        return 0;
    }

    声明多写了一个o。

    7.22

    #include <iostream>
    #include <string>
    using namespace std;
    
    // Person.h
    class Person {
    friend istream &read(istream &is, Person &p);
    public:
        Person() = default;
        Person(const string &name): name(name) {}
        Person(const string &name, const string &address): name(name), address(address) {}
        Person(istream&);
        string getName() const { return name; }
        string getAddress() const  { return address; }
    private:
        string name;
        string address;
    };
    istream &read(istream&, Person&);
    ostream &print(ostream&, const Person&);
    
    // Person.cpp
    istream &read(istream &is, Person &p)
    {
        is >> p.name >> p.address;
        return is;
    }
    ostream &print(ostream &os, const Person &p)
    {
        os << p.getName() << " " << p.getAddress();
        return os;
    }
    Person::Person(istream &is)
    {
        read(is, *this);
    }
    
    // main.cpp
    int main()
    {
        Person p1;
        Person p2("xklf");
        Person p3("llyy", "china");
        Person p4(cin);
        print(cout, p1) << endl;
        print(cout, p2) << endl;
        print(cout, p3) << endl;
        print(cout, p4) << endl;
        return 0;
    }
  • 相关阅读:
    codevs1735 方程的解数(meet in the middle)
    cf280C. Game on Tree(期望线性性)
    使用ASP.NET上传多个文件到服务器
    Oracle DB 数据库维护
    poj 3237(树链剖分+线段树)
    undefined reference to 'pthread_create'
    ios开发-调用系统自带手势
    Mysql创建、删除用户、查询所有用户等教程,提升您的MYSQL安全度!
    Number Sequence_hdu_1005(规律)
    SCU 4313 把一棵树切成每段K个点 (n%k)剩下的点不管
  • 原文地址:https://www.cnblogs.com/xkxf/p/6687421.html
Copyright © 2011-2022 走看看