《C++ Primer》第2章 2.6节习题答案

2.5 自定义数据结构

 

练习39:编译下面的程序观察其运行结果,注意,如果忘记写类定义体后面的分号会发生什么情况?记录下相关信息,以后可能会有用。
struct Foo {/*此处为空*}   //注意:没有分号
int main()
{
    return 0;
}
【解答】
该程序无法编译通过,原因是缺少一个分号。因为类体后面可以紧跟变量名以示对该类型对象的定义,所以在类体右侧表示结束
的花括号后必须写一个分号。稍作修改,该程序就可以编译通过 了。
struct Foo {/*此处为空*};
int main()
{
    return 0;
}

练习40:根据自已的理解写出Sales_data类,最好与书中的例子有所区别。
【解答】
原书中的程序包含3个数据成员,分别是bookNo(书籍编号)、units_sold(销售量)、revenue(销售收入),新设计的
Sales_data类细化了销售收入的计算方式,在保留bookNo和units_sold的基础上,新增了sellingprice(零售价、原价)、
saleprice(实售价、折扣价)、discount(折扣),其中discount=saleprice/sellingprice。
struct Sales_data{
    std::string bookNo;            //书籍编号
    unsigned units_sold = 0;    //销售量
    double sellingprice = 0.0;    //零售价
    double saleprice = 0.0;        //实售价
    double discount = 0.0        //折扣
};

 

练习41:使用你自己的Sales_data类重写1.5.1节(第20页)、1.5.2节(第21页)和1.6节(第22页)的练习。眼下先把Sales_data类的定义和main函数放在同一个文件里。

#include <iostream>
#include <string>


using namespace std;


class Sales_data{
    
    //友元函数
    friend std::istream& operator >> (std::istream&, Sales_data&);
    //友元函数
    friend std::ostream& operator << (std::ostream&, const Sales_data&);
    //友元函数
    friend bool operator < (const Sales_data &, const Sales_data &);
    //友元函数
    friend bool operator == (const Sales_data &, const Sales_data &);
    
public: //构造函数的3种形式
    Sales_data() = default;
    Sales_data(const std::string &book):
    bookNo(book) { }
    Sales_data(std::istream &is) { is >> *this; }
    
public:
    Sales_data& operator += (const Sales_data&);
    std::string isbn() const
    {
        return bookNo;
    }
    
private:
    std::string bookNo;        //书籍编号,隐式初始化为空串
    unsigned units_sold = 0;   //销售量,显示初始化为0
    double sellingprice = 0.0; //原始价格,显示初始化为0.0
    double saleprice = 0.0;    //实售价格,显示初始化为0.0
    double discount = 0.0;     //折扣,显示初始化为0.0
};




inline bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs)
{
    return lhs.isbn() == rhs.isbn();
}


Sales_data operator + (const Sales_data&, const Sales_data&);


inline bool operator == (const Sales_data &lhs, const Sales_data &rhs)
{
    return lhs.units_sold == rhs.units_sold && \
            lhs.sellingprice == rhs.sellingprice && \
            lhs.saleprice == rhs.saleprice && \
            lhs.isbn() == rhs.isbn();
}


inline bool operator != (const Sales_data &lhs, const Sales_data &rhs)
{
    return !(lhs == rhs);  //基于运算符 == 给出 !=的定义
}


Sales_data& Sales_data::operator += (const Sales_data& rhs)
{
    units_sold += rhs.units_sold;
    saleprice = (rhs.saleprice * rhs.units_sold + saleprice * units_sold) \
    / (rhs.units_sold + units_sold);
    if(sellingprice != 0)
        discount = saleprice / sellingprice;
    
    return *this;
}


Sales_data operator + (const Sales_data& lhs, const Sales_data& rhs)
{
    Sales_data ret(lhs);  //把lhs的内容拷贝到临时变量ret中,这种做法便于运算
    ret += rhs;           //把rhs的内容加入其中
    return ret;           //返回ret
}


std::istream& operator >> (std::istream& in, Sales_data& s)
{
    in >> s.bookNo >> s.units_sold >> s.sellingprice >> s.saleprice;
    if((in && s.sellingprice) != 0)
        s.discount = s.saleprice / s.sellingprice;
    else
        s = Sales_data();  //输入错误,重置输入的数据
    
    return in;
}


std::ostream& operator << (std::ostream& out, const Sales_data& s)
{
    out << s.isbn() << "  " << s.units_sold << "  " << s.sellingprice \
        << "  " << s.saleprice << "  " << s.discount;
    
    return out;
}


int main()
{
    Sales_data book;
    std::cout << "请输入销售记录:" << std::endl;
    while(std::cin >> book)
    {
        std::cout << " ISBN,售出本数,原始价格,实售价格,折扣为" << book << std::endl;
    }
    
    Sales_data trans1, trans2;
    std::cout << "请输入两条ISBN相同的销售记录:" << std::endl;
    std::cin >> trans1 >> trans2;
    if(compareIsbn(trans1, trans2))
        std::cout << "汇总信息:ISBN,售出本数,原始价格,实售价格,折扣为" << trans1 + trans2 << std::endl;
    else
        std::cout << "两条销售记录的ISBN不同" << std::endl;
    
    Sales_data total, trans;
    std::cout << "请输入几条ISBN相同的销售记录:" << std::endl;
    if(std::cin >> trans)
    {
        while(std::cin >> trans)
            if(compareIsbn(total, trans))  //ISBN相同
            {
                total = total + trans;
            }
            else  //ISBN不同
            {
                std::cout << "当前书籍ISBN不同" << std::endl;
                break;
            }
        
    }
    else
    {
        std::cout << "没有数据" << std::endl;
        return -1;
    }
    
    int num = 1;  //记录当前书籍的销售记录总数
    std::cout << "请输入若干销售记录:" << std::endl;
    
    if(std::cin >> trans1)
    {
        while(std::cin >> trans2)
            if(compareIsbn(trans1, trans2))  //ISBN相同
            {
                num++;
            }
            else   //ISBN不同
            {
                std::cout << trans1.isbn() << "共有" << num << "条销售记录" << std::endl;
                trans1 = trans2;
                num = 1;
            }
        std::cout << trans1.isbn() << "共有" << num << "条销售记录" << std::endl;
    }
    else
    {
        std::cout << "没有数据" << std::endl;
        return -1;
    }
    
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值