C++Primer第五版 第7章 类 7.1 定义抽象数据类型 练习

C++ Primer》(第五版)详细目录 c++primer 阅读详情

C++Primer第五版 第7章 类 练习

7.1 定义抽象数据类型

练习7.1.1

练习7.1.1:使用2.6.1节练习定义的Sales_data类为1.6节(第21页)的交易处理程序编写一个新版本。

#include <iostream>
#include <string>
using namespace std;
struct Sales_data{
	string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
};
void test(){
	Sales_data 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){ // 检查isbn
				total.units_sold += trans.units_sold;
                total.revenue += trans.revenue; // 更新变量total当前的值
			}else {
				cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;	// 输出结果
                total = trans; // 处理下一本书
			} 
		 }
		 cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl; // 输出最后的一条交易
	} else { //没有输入任何信息
		cerr << "No data?!" << endl; // 通知用户
	}
}

int main(){	
	test();
	system("pause");
    return 0;
}
练习7.1.2

练习7.2:曾在2.6.2节练习(第67页)中编写了一个Sales_data类,请向这个类添加combine和isbn成员。

//一个定义了Sales_data类的头文件Sales_data.h
#include <iostream>
#include <string>
using namespace std;
struct Sales_data{
	//关于Sales_data对象的操作
	string isbn() const {return this->bookNo;}//返回对象的isbn编号
	Sales_data& combine(const Sales_data&);//将一个Sales_data对象加到另一个对象上
	double avg_price() const;//返回售出书籍的平均价格
	
	string bookNo;	//表示isbn编号
	unsigned units_sold = 0;	//书的销量
	double revenue = 0.0;	//书的总销售收入
};
double Sales_data::avg_price()const{//常量成员函数,不会改变Sales_data对象的值
	if(units_sold)
		return revenue/units_sold;
	else
		return 0;
}
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
	 units_sold += rhs.units_sold; //把rhs的成员加到this对象的成员上
	 revenue += rhs.revenue; 
	 return *this; //返回调用该函数的对象
}

练习7.3:修改7.1.1节(第229页)的交易处理程序,令其使用这些成员。

#include <iostream>
#include <string>
#include "Sales_data.h"
using namespace std;

void test(){
	Sales_data total; // 保存当前求和结果的变量
	if (cin >> total.bookNo >> total.units_sold >> total.revenue) { // 读入第一笔交易
		 Sales_data trans; // 保存下一条交易数据的变量
		 while(cin >> trans.bookNo >> trans.units_sold >> trans.revenue) { // 读入剩余的交易
			if (total.isbn() == trans.isbn()){ // 检查isbn
				total.combine(trans);// 更新变量total当前的值
			}else {
				cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;	// 输出结果
                total = trans; // 处理下一本书
			} 
		 }
		 cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl; // 输出最后的一条交易
	} else { //没有输入任何信息
		cerr << "No data?!" << endl; // 通知用户
	}
}

int main(){
	test();
	system("pause");
    return 0;	
}

练习7.4:编写一个名为Person的类,使其表示人员的姓名和地址。使用string对象存放这些元素,接下来的练习将不断充实这个类的其他特征。

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

class Person{
public:
	string mName;//人员姓名
	string mAddress;//人员地址
};

练习7.5:在你的Person类中提供一些操作使其能够返回姓名和住址。这些函数是否应该是
const的呢?解释原因。 答:是const的,原因是这些操作不需要改变对象中成员变量的具体的值,只需要读取成员对象。

练习7.1.3

练习7.6:对于add, read和print,定义你自己的版本。

Sales_data add(const Sales_data& lhs, const Sales_data& rhs){
	Sales_data sum = lhs;
	sum.combine(rhs);
	return sum;
}
ostream &print(ostream& os, const Sales_data& item){
	//将给定对象的内容打印到给定的流当中
	os << item.isbn() << " " << item.units_sold << " " 
	   << item.revenue << " " << item.avg_price(); 
	return os;

}
istream &read(istream& is, Sales_data& item){
	//从给定流中将数据读到给定对象中
	double price = 0.0;//每本书的单价
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = price * item.units_sold;
	return is;
}

练习7.7:使用这些新函数重写7.1.2节(第233页)练习中的交易处理程序。

void test(){
	Sales_data total; // 保存当前求和结果的变量
	if (read(cin,total)) { // 读入第一笔交易
		 Sales_data trans; // 保存下一条交易数据的变量
		 while(read(cin,trans)) { // 读入剩余的交易
			if (total.isbn() == trans.isbn()){ // 检查isbn
				total.combine(trans);// 更新变量total当前的值
			}else {
				print(cout,total);	// 输出结果
                total = trans; // 处理下一本书
			} 
		 }
		 print(cout,total); // 输出最后的一条交易
	} else { //没有输入任何信息
		cerr << "No data?!" << endl; // 通知用户
	}
}

练习7.8:为什么read函数将其Sales_data参数定义成普通的引用,而print将其参数定义成常量引用?
答: read函数是从给定流中将数据读到给定对象中,需要对Sales_data对象进行改变,其中成员变量revenue,bookNo等全部被更新;而print函数是将给定对象的内容打印到给定的流当中,不需要对Sales_data对象进行改变,只需要读取成员对象

练习7.9:对于7.1.2节(第233页)练习中的代码,添加读取和打印Person对象的操作。

istream &read(istream &is, Person &person)
{
    return is >> person.mName >> person.mAddress;
}

ostream &print(ostream &os, const Person &person)
{
    return os << person.mName << " " << person.mAddress;
}

练习7.10:在下面这条if语句中,条件部分的作用是什么?
if(read(read(cin,data1),data2))
答:read(cin,data1) ,向data1里输入内容,返回data1;read(read(cin,data1),data2) 即为read(data1,data2),将data1的内容输入到data2;只有当两次读入的内容都不空时,条件为真。

练习7.1.4

练习7.11:在你的Sales_data类中添加构造函数,然后 编写一段程序令其用到没个构造函数

Sales_Data.h
struct Sales_data{
	//构造函数 (在类外实现)
	Sales_data();
	Sales_data(const string &s);
	Sales_data(const string &s, unsigned n, double p);
	Sales_data(istream &);

	//关于Sales_data对象的操作
	string isbn() const {return  bookNo;}//返回对象的isbn编号
	Sales_data& combine(const Sales_data&);//将一个Sales_data对象加到另一个对象上
	double avg_price() const;//返回售出书籍的平均价格
	
	string bookNo;	//表示isbn编号
	unsigned units_sold = 0;	//书的销量
	double revenue = 0.0;	//书的总 销售收入
};
Sales_data.cpp
// 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) { }
// // : bookNo(s), units_sold(n), revenue(p*n)  构造函数初始化列表
Sales_data::Sales_data(istream &is){
	read(is, *this); //read函数的作用是从is中读取一条交易信息然后存入this对象中
}
Sales_data::Sales_data(const string &s, unsigned n, double p){ 
	this->bookNo = s;
	this->units_sold = n;
	this->revenue = p*n ;
} 
Sales_data::Sales_data(const string &s) { 
	this->bookNo = s;
} 
// Sales_data::Sales_data(){}
Sales_data::Sales_data() = default;

void test(){
	Sales_data total01;
	print(cout,total01);	
	cout << endl;
	
    Sales_data total02("1234");
	print(cout,total02);	
	cout << endl;
	
	Sales_data total03("1200",3,3.59);
	print(cout,total03);	
	cout << endl;
	
	Sales_data total04(cin);
	print(cout,total04);
}

在这里插入图片描述

练习7.12:把只接受一个istream作为参数的构造函数定义到类的内部。

Sales_Data.h
struct Sales_data{

	friend istream &read(istream&, Sales_data&);//read函数做友元
	
	//构造函数 
	Sales_data(istream &is){
		read(is, *this); //read函数的作用是从is中读取一条交易信息然后存入this对象中
	}
	
	//关于Sales_data对象的操作
	string isbn() const {return  bookNo;}//返回对象的isbn编号
	Sales_data& combine(const Sales_data&);//将一个Sales_data对象加到另一个对象上
	double avg_price() const;//返回售出书籍的平均价格

	string bookNo;	//表示isbn编号
	unsigned units_sold = 0;	//书的销量
	double revenue = 0.0;	//书的总 销售收入
};

练习7.13:使用istream构造函数重写第229页程序。

Sales_Data.h
struct Sales_data;
istream &read(std::istream&, Sales_data&);

struct Sales_data{	
	//构造函数 
	Sales_data();
	// Sales_data() = default;
	Sales_data(const string &s);
	Sales_data(const string &s, unsigned n, double p);
	Sales_data(istream &is){
		read(is, *this); //read函数的作用是从is中读取一条交易信息然后存入this对象中
	}

	//关于Sales_data对象的操作
	string isbn() const {return  bookNo;}//返回对象的isbn编号
	Sales_data& combine(const Sales_data&);//将一个Sales_data对象加到另一个对象上
	double avg_price() const;//返回售出书籍的平均价格
	
	string bookNo;	//表示isbn编号
	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&);

练习7.14:编写一个构造函数,令其用我们提供的类内初始值显示地初始化成员

void test(){
	Sales_data total(cin); // 读入第一笔交易
	if (!total.isbn().empty()) {  
		 istream &is = cin;// 读入剩余的交易
		 while(is) { 
			Sales_data trans(is);// 保存下一条交易数据的变量
            if (!is) break;//剩余交易没有输入,中止输入
			if (total.isbn() == trans.isbn()){ // 检查isbn
				total.combine(trans);// 更新变量total当前的值
			}else {
				print(cout,total)<<endl;// 输出结果
                total = trans; // 处理下一本书
			} 
		 }
		 print(cout,total)<<endl; // 输出最后的一条交易
	} else { //没有输入任何信息
		cerr << "No data?!" << endl; // 通知用户
	}
}

练习7.15:为你的Person类添加正确的构造函数

Person.h
class Person{
public:
	friend istream &read(istream &, Person &);
	
	Person(){}
	Person(string name,string address):mName(name), mAddress(address){}
	Person(istream& is){
		read(is,*this);
	}
	string mName;//人员姓名
	string mAddress;//人员地址
	
};
// istream &read(istream &, Person &);
ostream &print(ostream &, const Person &);
Person.cpp
istream &read(istream &is, Person &person)
{
    return is >> person.mName >> person.mAddress;
}

ostream &print(ostream &os, const Person &person)
{
    return os << person.mName << " " << person.mAddress;
}
int main(){
	Person p1;
	print(cout,p1) << endl;
	
	Person p2("张三","北京市海淀区");
	print(cout,p2) << endl;
	
	Person p3(cin);
	print(cout,p3) << endl;
	
	system("pause");
    return 0;
}
练习7.1.5

无练习

c++primer 第七习题答案 7.7 //2018年8月17练习7.7 Sales_data total; if (read(cin, total)) { sales_data trans; while (read(cin, trans)) { if (total.isbn() = trans.isbn()) { total.combine(trans); } else { print(co... 阅读详情

相关推荐

Shader之——花草动画shader

今天 ,接到了个需求,花草的动画。谈到花草动画,立马就想到顶点动画,让顶点动起来就可以实现了。但是有个问题,所有的草都往一个方向运动,这个就麻烦了。因为在shader里没有随机这种概念,提到最多的是用一张噪声图来模拟。在网上搜索了一下,发现有更好的办法,就是用每个顶点到一个点的距离来控制动画的开始,毕竟每个顶点到同一个点的距离很少是一样的。 float dis = distance ...

baicaishisan的博客 2156

C++ Primer(第五版) 7.1.1--7.1.3节练习

7.1 Sales_data: #ifndef SALES_DATA_H #define SALES_DATA_H #include <iostream> #include <string> using namespace std; struct Sales_data { string bookNo; unsigned units_sold = 0; ...

wlli1985的博客 539

STM32H743必要外围电路分析

写在前面:这篇博客是我第一次绘制STM32最小系统板的过程记录。 2020-1-11 BOOT STM32采用ARM内核,和ARM处理器一样,都有专门的boot脚决定单片机从何处启动。 在官方数据手册的第105页,我们可以看到 系统复位后,在SYSTICK的第四个上升沿锁存BOOT引脚的值,复位后,BOOT引脚可以由用户自由配置而不会影响系统正常运行。 BOOT引脚决定了自举存储器地址,当BO...

Cui_Hongwei的博客 1万+

C++ Primer -定义抽象数据类型

例如,sales_item是一个抽象数据类型,我们通过它的接口描述的操作)来使用一个Salesitem对象,我们不能访问Salesitem对象的数据成员,事实上,我们甚至根本不知道这个有哪些数据成员。与之相反,Sales_data不是一个抽象数据类型。它允许的用户直接访问它的数据成员,并且要求由用户来编写操作。要想把Sales_data变成抽象数据类型,我们需要定义一些操作以供的用户使用。一旦Sales_data定义了它自己的操作,我们就可以封装(隐藏)它的数据成员了。

专注于C/C++编程语言的博客,如果读者对C/C++语言有任何需要咨询的可以私信联系! 1271

C++primer第七课后题7.1

C++中是非常重要的,少年要认真学,我简单的查了一下struct和class的区别 1C++ 中保留了C语言的 struct 关键字,并且加以扩充。在C语言中,struct 只能包含成员变量,不能包含成员函数。而在C++中,struct 似于 class,既可以包含成员变量,又可以包含成员函数。 2) class中的成员默认都是 private, struct 结构体中的成员默认都是 p...

qq_44899279的博客 246

C++ Primer7.1.4节练习

练习7.11: #include <iostream> #include <cstring> using namespace std; class Sales_data { public: Sales_data() = default; Sales_data(const std::string &book): bookNo(book) {} Sales_data(const std::string &book, const unsigned num,

m0_51955470的博客 463

C++ Primer 第七 7.1 定义抽象数据类型 练习和总结

练习 关于的这部分内容,书上写得比较杂。先把练习给写上,总结到后面写。 7.1.1 完全没有任何封装得情况下,写得Sales_data得交易处理程序。 #include"pch.h" #include<iostream> #include<string> using std::cin; using std::cout; using std::ostream; usin...

大琪子的博客 338

c++primer练习7.17.2、7.3、7.4、7.5、7.6、7.77.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;

一个搬运知识的笨小孩 600

C++ Primer》导学系列:第 7 -

C++中,是用户定义型,提供了一种将数据和操作这些数据的函数(成员函数)组合在一起的方法。定义了对象的属性和行为,通过实例化来创建对象。定义时,需要指定的名称,并在体内声明数据成员和成员函数。public:// 成员函数声明private:// 数据成员声明本节总结学习了定义和基本概念,掌握了成员函数和数据成员的声明与定义方法。理解了构造函数的作用和定义方法,掌握了构造函数初始化列表的使用。通过示例代码和练习题,加深了对的接口和实现的理解和应用。提高建议。

iShare_Carlos的博客 1542

C++|C++ primer7

C++ 语言中,我们使用定义自己的数据型。通过定义新的型来反映待解决问题中的各种概念,可以使我们更容易编写、调试和修改程序。 的基本思想是数据抽象(data abstraction)和封装(encapsulation)。数据抽象是一种依赖于接口(interface)和实现(implementation)分离的编程(以及设计)技术。的接口包括用户所能执行的操作;的实现则包括的数据成员、负责接口实现的函数体以及定义所需的各种私有函数。 封装实...

kllo__的博客 1528

C++(一):定义抽象数据类型

C++ Primer的第七第一节:定义抽象数据类型 进行学习和记录。

YGGP的博客 1191

c++ Primer 第七 练习答案记录

c++ Primer 第七 练习答案记录

Is_Superman的博客 2018

C++ Primer 第五版7 7.1——讲解(成员函数、非成员函数、构造函数)习题答案

理论讲解请参考:C++ Primer 第五版7 7.1——讲解(成员函数、非成员函数、构造函数) 目录 7.1 定义抽象数据类型习题答案 7.4&amp;7.5 7.6&amp;7.7 7.8 7.9 7.10 7.15 7.1 定义抽象数据类型习题答案 7.4&amp;7.5 应该定义为const型,这里没有涉及到对对象的修改。考点:是否设置const...

中科院AI算法工程师的博客 535

C++ Primer》第7 7.1节习题答案

C++ Primer》第7 7.1节习题答案

chenyijun的专栏 458

C++Primer学习(7.1 定义抽象数据类型

回忆我们之前介绍过的,如果定义在块中的内置型或复合型(比如数组和指针)的对象被默认初始化,则它们的值将是未定义的。任何对成员的直接访问都被看作 this 的隐式引用,也就是说,当isbn 使用 bookNo 时,它隐式地使用 this 指向的成员,就像我们书写了this->bookNo一样。和其他成员函数一样,当我们在的外部定义构造函数时,必须指明该构造函数是哪个的成员。和其他函数一样,如果=default在的内部,则默认构造函数是内联的:如果它在的外部,则该成员默认情况下不是内联的。

wgf350357114的博客 940

C++Primer第五版 7.1.2节练习

练习7.2:曾在2.6.2节练习(第67页)中编写了一个Sales_data,请向这个添加combine和isbn成员。 练习7.3:修改7.1.1节(第229页)的交易处理程序,令其使用这些成员。 练习7.4:编写一个名为Person的,使其表示人员的姓名和地址。使用string对象存放这些元素,接下来的练习将不断充实这个的其他特征。 答:练习7.2-7.3见云盘程序。练习7.5:在

Nick Feng 的小屋 1954

C++Primer练习[第七]

//练习7.1:使用2.6.1练习定义的Sales_data1.6节(第21页)的交易处理程序编写一个新版本。/*#include &lt;iostream&gt;#include &lt;string&gt;using std::string;using std::cin;using std::cout;using std::endl;using std::cerr;struct Sale...

sukeychen的博客 1523

C++primer 7.1部分习题(一)

7.1.1 头文件 Sd.h #pragma once #ifndef SD_H_INCLUDED #define SD_H_INCLUDED #include<iostream> #include<string> class Sd { friend std::istream& operator>>(std::istream&, Sd&am...

xhh22900的博客 259

C++Primer第五版 7.1.1练习

练习7.1:使用2.6.1练习定义的Sales_data1.6节(第21页)的交易处理程序编写一个新版本。 答案:见云盘程序 练习7.1.cpp。 练习7.1/* *练习7.1 *日期:2015/6/30 *问题描述:练习7.1:使用2.6.1练习定义的Sales_data1.6节(第21页)的交易处理程序编写一个新版本。 *功能;使用一个定义的结构体来重写21页那个程序 *说明:这

Nick Feng 的小屋 1709

五、C++新特性、关键字与编译原理

本文系统梳理了25项C++核心知识,涵盖新特性、关键字与编译原理。重点解析了const、static、extern等关键字用法,对比了#define与const、sizeof与strlen等核心概念差异。深入探讨了C++11/17/20/23新特性在AI领域的应用,包括移动语义减少数据拷贝、STL容器选择策略及RAII资源管理机制。同时涉及高性能编程要素(string_view、span)、模板元编程技术(CRTP、型擦除)和工程实践要点(CMake管理、ABI兼容性、extern "C&quo

Question_123456的博客 140

cobalt strike 4.7

cobalt strike 4.7

上一篇: Java开发实战经典
下一篇: C++Primer第五版 第7章 类 7.2访问控制与封装&友元 练习
Fern_v
博客等级 码龄7年 288粉丝 45原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值