练习7.20:友元什么时候有用?请分别列举出使用友元的利弊。
答:类可以允许其他类或者函数访问它的非公有成员,方法是令其他类或者函数成为它的友元。利:可以让别的类或函数访问类的私有数据成员。弊:数据成员的安全性可能会降低。
练习7.21:修改你的Sales_data类使其隐藏实现的细节。你之前编写的关于Sales_data操作的程序应该继续使用,借助类的新定义重新编译该程序,确保其工作正常。
答:见云盘程序 练习7.21.cpp
练习7.22:修改你的Person类使其隐藏实现的细节。
答:见云盘程序 练习7.22.cpp
练习7.21
/*
*练习7.21
*日期:2015/7/6
*问题描述:练习7.21:修改你的Sales_data类使其隐藏实现的细节。你之前编写的关于Sales_data操作的程序应该继续使用,借助类的新定义重新编译该程序,确保其工作正常。
*功能;使用访问说明符
*作者:Nick Feng
*邮箱:nickgreen23@163.com
*/
#include <iostream>
#include <string>
using namespace std;
class Sales_data{
public:
friend istream &read(istream &, Sales_data &);//一个友元函数read,便于Sales_data类直接访问
friend ostream &print(ostream &os, const Sales_data &item);
Sales_data() = default;//默认构造函数
Sales_data(const std::string &s) : bookNo(s){ }
Sales_data(const std::string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n){ }
Sales_data(std::istream &is){
read(is,*this);
}
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 add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);
double Sales_data::avg_price() const{
if (units_sold)
return revenue/units_sold;
else
return 0;
}
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;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs){
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
/*
Sales_data::Sales_data(std::istream &is)
{
read(is,*this);
}
*/
int main()
{
Sales_data s1("Hero!I am");//调用第一种构造函数
print(cout, s1);
cout << endl;
Sales_data s2("Hero!I am",10,20);//调用第二种构造函数
print(cout,s2);
cout << endl;
Sales_data s3(cin);//调用第三种构造函数
print(cout,s3);
cout << endl;
return 0;
}
练习7.22
/*
*练习7.22
*日期:2015/7/6
*问题描述:练习7.22:修改你的Person类使其隐藏实现的细节。
*功能;使用访问说明符
*作者:Nick Feng
*邮箱:nickgreen23@163.com
*/
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
friend istream& read(istream &is, Person &p); //声明友元,可以访问私有成员
friend ostream& print(ostream &out,const Person &p);//声明友元,可以访问私有成员
Person()=default;
Person(string na, string ad) : name(na),address(ad){}
string getName() const {return name;}
string getAddress() const{return address;}
private:
string name;
string address;
};
istream& read(istream &is, Person &p)
{
is >> p.name >> p.address;
return is;
}
ostream& print(ostream &out,const Person &p)
{
out << "Name: " << p.name << "\n" << "Address: " << p.address;
return out;
}
int main()
{
Person p1("Nick","Nanjing");
print(cout,p1) << endl;
Person p2;
read(cin,p2);
print(cout,p2) << endl;
return 0;
}