• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

【c++primer,5e】访问控制与封装

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

练习

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;
}

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap