【c++ primer, 5e】设计Sales_data类 & 定义改进的Sales_data类

【设计Sales_data类】

 1、考虑Sales_data类应该有那些接口。

 isbn、combine、add、read、print...

  

2、考虑如何使用这些接口。

Sales_data total;
if (read(cin, total)) {
    Sales_data trans;
    while (read(cin, trans)) {
        if (total.isbn() == trans.isbn())
            total.combine(trans);
        else {
            print(cout, total) << endl;
            total = trans;
        }
    }
    print(cout, total) << endl;
} else {
    cerr << "No data?!" << endl; 
}

练习

7.1

#include <iostream>
#include <string>
struct Sales_data {
    std::string bookNo;
    unsigned units_sold = 0;
    double price = 0.0;
    double revenue = 0.0;
};
int main()
{
    Sales_data total;
    if (std::cin >> total.bookNo >> total.units_sold >> total.price) {
        Sales_data trans;
        while (std::cin >> trans.bookNo >> trans.units_sold >> trans.price) {
            if(total.bookNo == trans.bookNo) {
                total.units_sold += trans.units_sold;
            } else {
                std::cout << total.bookNo << " " << total.units_sold << " " << total.price << std::endl;
                total = trans;
            }
        }
        std::cout << total.bookNo << " " << total.units_sold << " " << total.price << std::endl;
    } else {
        std::cerr << "No data?" << std::endl;
        return -1;
    }
    return 0;
}

 【定义改进的Sales_data类】

struct Sales_data {
    // public部分,对象看起来是怎么样的。
    std::string isbn() const { return bookNo; } // inline function
    Sales_data& combine(const Sales_data&);
    double avg_price() const;
    // private部分,数据成员。
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};
// Sales_data的非成员接口函数
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);

this与const成员函数

1、可以通过return *this;返回对象本身。

2、在某个类的成员函数声明(定义)的参数列表之后加上const,意味着该函数所使用的隐式参数T *const this被修改为const T *const this,它们之间的区别在于,前者无法持有常量对象,而后者既可以持有常量对象也可以持有非常量对象。

因此,const成员函数的引入提高了函数的灵活性,使得const obj可以调用相应的常量成员函数。

练习

7.2 & 7.3

#include <iostream>
#include <string>
using namespace std;

// Sales_data.h
struct Sales_data {
    // public部分,对象看起来是怎么样的。
    std::string isbn() const { return bookNo; } // inline function
    Sales_data& combine(const Sales_data&);
    double avg_price() const;
    // private部分,数据成员。
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};
// Sales_data的非成员接口函数
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::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;
}

// main.cpp
int main()
{
    Sales_data total;
    if (std::cin >> total.bookNo >> total.units_sold) {
        Sales_data trans;
        while (std::cin >> trans.bookNo >> trans.units_sold) {
            if (total.isbn() == trans.isbn())
                total.combine(trans);
            else {
                std::cout << total.bookNo << " " << total.units_sold << " "  << std::endl;
                total = trans;
            }
        }
        std::cout << total.bookNo << " " << total.units_sold << " " << std::endl;
    } else {
        cerr << "No data?!" << endl; 
    }
    return 0;
}

7.4

#include <iostream>
#include <string>
using namespace std;
// Person.h
struct Person {
    string name;
    string address;
}
// Person.cpp
// main.cpp

7.5

应该加const。因为不论是常量对象还是非常量对象都有权访问自己的姓名和住址,这个操作并没有涉及改变对象的数据成员。

什么时候不加const?调用者不希望常量对象调用该函数的时候就不加const,例如书上的combine函数。

当函数只涉及“访问”而不涉及“改变”的时候加const,当函数涉及“改变”的时候不加const。

原文地址:https://www.cnblogs.com/xkxf/p/6664396.html