c++primer练习7.1、7.2、7.3、7.4、7.5、7.6、7.7、7.8、7.9、7.10
·
练习7.1
使用65页练习定义的Sales_data类为21页的书店交易处理程序编写一个新版本
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::cerr;
struct Sales_data{
string bookNo;
unsigned units_sold = 0;
double revenue;
};
int main(){
Sales_data total; //将每个ISBN的所有数据合并起来存如total变量中
if (cin >> total.bookNo >> total.units_sold >> total.revenue){ //如果有数据输入
Sales_data trans; //读取第二个对象
while (cin >> trans.bookNo >> trans.units_sold >> trans.revenue){
if(total.bookNo == trans.bookNo){ //比较两个对象(书)的书号
total.units_sold += trans.units_sold; //同一种书的售出数量相加
total.revenue += trans.revenue; //价格相加
} else{ //不是同一种书
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl; //打印出第二本数的信息
total = trans; //将第二本书的信息赋值给对象total以便下一次trans读取下一本书后可以进行比较
}
}//输出最后一本书的数据
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;
} else { //无数据输入
cerr << "No data?" << endl;
return -1;
}
return 0;
}
练习7.2
向67页中Sales_data类添加combine和isbn成员
(写入头文件ex02.h)
#ifdef EX7_02_H
#define EX7_02_H
#include <string>
struct Sales_data{
//const是修饰隐式this指针的
std::string isbn() const {return bookNo; } //this指针所存地址不能被改变,即所指对象不能改变
//返回类型为引用类型,此后对引用的操作就是对对象本身的操作
Sales_data& combine(const Sales_data&); //参数为引用类型,对实参的引用,函数中对参数的操作就是对实参的改变,const表明此函数体中的操作不会对该参数进行改变
};
Sales_data& combine(const Sales_data&){ //含隐式形参this指针
//lhs.combine(rhs);
//this指针指对象是lhs
units_sold += rhs.units_sold;
//等价于lhs.units_sold = lhs.units_sold + rhs.units_sold
revenue += rhs.revenue;
//lhs.revenue = lhs.revenue + rhs.revenue
return *this; //解引用this指针获得对象(上述注释中的对象lhs)
//函数返回类型为引用(别名)类型(不进行对象拷贝),即等价于直接返回对象
}
#endif
练习7.3
修改229页的交易处理程序,令其使用这些成员
#include <iostream>
#include "ex02.h"
using std::cin;
using std::cout;
using std::endl;
int main(){
Sales_data total; //将每个ISBN的所有数据合并起来存如total变量中
if (cin >> total.bookNo >> total.units_sold >> total.revenue){ //如果有数据输入
Sales_data trans; //读取第二个对象
while (cin >> trans.bookNo >> trans.units_sold >> trans.revenue){
if(total.bookNo == trans.bookNo){ //比较两个对象(书)的书号
total.units_sold += trans.units_sold; //同一种书的售出数量相加
total.revenue += trans.revenue; //价格相加
} else{ //不是同一种书
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl; //打印出第二本数的信息
total = trans; //将第二本书的信息赋值给对象total以便下一次trans读取下一本书后可以进行比较
}
}//输出最后一本书的数据
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;
} else { //无数据输入
cerr << "No data?" << endl;
return -1;
}
return 0;
}
练习7.4
编写一个名为Person的类,使其表示人员的姓名和住址.使用string对象存放这些元素
(写在名为头文件ex04.h中)
#ifndef EX7_04_H
#define EX7_04_H
#include<string>
class Person{
std::string name
std::string address;
};
#endif
练习7.5
在你的Person类中提供一些操作使其能够返回姓名和住址.这些函数是否应该是const的呢?
#ifndef EX7_05_H
#define EX7_05_H
#include<string>
class Person{
std::string name
std::string address;
public:
//const成员函数,this指针所存地址不能被改变,即所指对象不能改变
//尾置返回类型方式,返回类型(箭头运算符右侧的部分)为指向函数的指针
auto get_name() const -> std::string const& { return name; }
auto get_addr() const -> std::string const& { return address; }
};
#endif
练习7.6
定义函数add、read、print
(ex06.h)
//lhs.add(rhs);
//lhs为左侧对象,rhs为右侧对象,形参类型为引用类型(将形参绑定到实参上,函数体对形参的操作就是对实参的操作)
Sales_data add(const Sales_data &lhs, const Sales_data &rhs){
Sales_data sum = lhs;
sum.combine(rhs);
return sum; //返回拷贝值(非引用类型)
}
//函数返回类型为引用(即返回对象属性的引用)
//形参类型为引用类型(将形参绑定到实参上,函数体对形参的操作就是对实参的操作)
//read函数从给定流中将数据读到给定的对象里
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; //返回输入流的引用(别名)
}
//print函数负责将给定对象的内容打印到给定的流中
ostream &print(ostream &os, const Sales_data &item){ //形参为流和对象
//将数据传给输出流
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.avg_price();
return os; //返回输出流的引用(别名)
}
练习7.7
使用这些新函数重写(233页)练习中的交易处理程序
#include <iostream>
#include "ex02.h"
#include "ex06.h"
using std::cin;
using std::cout;
using std::endl;
int main(){
Sales_data total; //将每个ISBN的所有数据合并起来存如total变量中
if (read(cin,total)){ //如果有数据输入
Sales_data trans; //读取第二个对象
while (read(cin,trans)){
if(total.bookNo == trans.bookNo){ //比较两个对象(书)的书号
add(total,trans); //价格相加
} else{ //不是同一种书
print(trans); //打印出第二本数的信息
total = trans; //将第二本书的信息赋值给对象total以便下一次trans读取下一本书后可以进行比较
}
}//输出最后一本书的数据
print(total);
} else { //无数据输入
cerr << "No data?" << endl;
return -1;
}
return 0;
}
练习7.8
为什么read函数将其Sales_data参数定义成普通的引用,而print将其参数定义成常量引用?
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; //返回输入流的引用(别名)
}
- Define read’s Sale_data parameter as plain reference since it’s intended to change the revenue’s value
ostream &print(ostream &os, const Sales_data &item){ //形参为流和对象
//将数据传给输出流
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.avg_price();
return os; //返回输出流的引用(别名)
}
- Define print’s Sale_data parameter as a reference to const since it isn’t intended to change any member’s value of this object
练习7.9
为233页练习中的代码添加读取和打印 Person 对象的操作
istream &read(istream &is, Person &psn){
is >> psn.name >> psn.address;
return is;
}
ostream &print(ostream &os, const Person &psn){
os << psn.name << " " << psn.address;
return os;
}
练习7.10
下面 if 语句中,条件部分的作用是什么?
the condition of the if statement would read two Sales_data object at one time
if(read(read(cin,data1),data2))
we can try to divide it like that:
std::istream &firstStep = read(cin, data1);
std::istream &secondStep = read(firstStep, data2);
if(secondStep)
更多推荐
所有评论(0)