C++ Primer(第五版)第七章 类 部分答案

练习7.2

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

创建头文件sales.h

#ifndef SALES_H
#define SALES_H

#include <string>
#include <stdlib.h>
using namespace std;

struct Sales_data
{
	string isbn() const  //返回书的编号
	{
		return bookNo;
	}

	Sales_data& combine(const Sales_data& rhs);

	string bookNo;  //书编号
	unsigned units_sold = 0;  //售出的册数
	double revenue = 0.0;  //总销售额
};
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.units_sold;
	return *this;
}
#endif;

练习7.3

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

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

//读取销售记录,生成每本书的销售报告,显示售出册数、总销售额和平均售价
int main()
{
	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())
				total.combine(trans);
			else
			{
				cout << total.bookNo << " 的总销售记录是:共售出 " << total.units_sold << " 本,总收入是 " << total.revenue;
				total = trans;
			}
		}
		cout << total.bookNo  << " 的总销售记录是:共售出 " << total.units_sold << " 本,总收入是 " << total.revenue << " 平均每本价格是 "<<total.revenue/total.units_sold;
	}
}

练习7.4

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

创建头文件person.h

#pragma once
#include<string>
using namespace std;
struct Person {
	string Name;
	string Address;
};

练习7.6

对于函数 add、read、和 print,定义你自己的版本。

创建头文件sales.h

#ifndef SALES_H
#define SALES_H

#include <string>
#include <stdlib.h>
using namespace std;

struct Sales_data
{
	string isbn() const
	{
		return bookNo;
	}

	Sales_data& combine(const Sales_data& rhs);

	istream& read(istream& is, Sales_data& item);
	ostream& print(ostream& os, Sales_data& item);
	Sales_data add(const Sales_data& lhs, const Sales_data& rhs);


	string bookNo;  //书编号
	unsigned units_sold = 0;  //售出的册数
	double revenue = 0.0;  //总销售额
};
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.units_sold;
	return *this;
}
istream& Sales_data::read(istream& is, Sales_data& item) //is用来代替cin,istream类和ostream类见后续的IO类型
{
	double price;
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = price * item.units_sold;
	return is;
}
ostream& Sales_data::print(ostream& os, Sales_data& item)
{
	os << item.isbn() << " 的总销售记录是:共售出 " << item.units_sold << " 本,总收入是 "
		<< item.revenue << " " << " 平均每本价格是 "<<item.revenue/item.units_sold;

	return os;
}
Sales_data Sales_data::add(const Sales_data& lhs, const Sales_data& rhs)
{
	Sales_data sum = lhs;  //把lhs的数据成员拷贝给sum
	sum.combine(rhs);  //把rhs的数据成员加到sum中
	return sum;
}

#endif;

练习7.7

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

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

//读取销售记录,生成每本书的销售报告,显示售出册数、总销售额和平均售价
int main()
{
	Sales_data total;  
	if (total.read(cin,total))
	{
		Sales_data trans;
		while (total.read(cin,trans))
		{
			if (total.isbn() == trans.isbn())
				total.combine(trans);
			else
			{
				total.print(cout,total);
				cout << endl;
				total = trans;
			}
		}
		total.print(cout, total);
		cout << endl;
	}
}

练习7.9

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

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

struct Person {
	string Name;
	string Address;

	istream& read(istream& is, Person& per);
	ostream& print(ostream& os, const Person& per);

};
istream& Person::read(istream& is, Person& per)
{
	is >> per.Name >> per.Address;
	return is;
}

ostream& Person::print(ostream& os, const Person& per)
{
	os << "名字为:" << per.Name << "  地址为:" << per.Address;
	return os;
}

练习7.14、7.15、7.22

7.14.编写一个构造函数,令其用我们提供的类内初始值显式地初始化成员。
7.15.为你的 Person 类添加正确的构造函数。
7.22.修改你的 Person 类使其隐藏实现的细节。

头文件

#pragma once
#include <string>
#include <iostream>
using namespace std;
'''构造函数可以有多个,发生了重载,实例化的时候只能调用一个'''
class Person 
{
public:
	//1、无参构造函数,可以直接Person p创建实例
	Person() = default;  
	//2、无参显示构造,可以直接Person p创建实例,和默认无参构造无法发生重载
	Person():Name("megumi"),Address("japan"){} 
	//3、有参构造函数,需要Person p("sanae","erci")创建实例
	Person(string N, string A) :Name(N), Address(A) {} 
	//4、类外构造函数的声明
	Person(istream& is);

	istream& read(istream& is, Person& per);  //读取函数
	ostream& print(ostream& os, const Person& per);  //输出函数
private:
	string Name;
	string Address;
};

//类外构造函数的定义
Person::Person(istream &is)
{
	read(is,*this);
}

istream& Person::read(istream& is, Person& per)
{
	is >> per.Name >> per.Address;
	return is;
}

ostream& Person::print(ostream& os, const Person& per)
{
	os << "名字为:" << per.Name << "  地址为:" << per.Address;
	return os;
}

主程序

#include <iostream>
using namespace std;
#include "person.h"
int main()
{
	//1和2采用这种实例化
	Person per;
	per.print(cout, per);
	cout<<endl;
	//3采用这种实例化
	Person per1("sanae","beijing");
	per1.print(cout,per1);
	cout<<endl;
	//4类外构造函数的使用
	Person per2(cin);
	per2.print(cout,per2);
	
}

练习7.23、7.24、7.26

头文件screen.h

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

class Screen
{
public:
	typedef string::size_type pos;

	Screen() = default;
	Screen(pos ht, pos wd) :height(ht), width(wd) { }
	Screen(pos ht,pos wd,char c):height(ht),width(wd),contents(ht*wd,c) { }

	char get() const   //读取光标处的字符
	{
		return contents[cursor];  //隐式内联
	}
	inline char get(pos ht, pos wd) const; //显示内联

	Screen& move(pos r, pos c);  //能在之后被设为内联

private:
	pos cursor = 0;
	pos height = 0, width = 0;
	string contents;
};
char Screen::get(pos r, pos c) const
{
	pos row = r * width;
	return contents[row + c];
}
inline Screen& Screen::move(pos r, pos c) //内联,最好用这种方法,容易理解
{
	pos row = r * width;
	cursor = row + c;
	return *this;
}

练习7.27

头文件screen.h

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

class Screen
{
public:
	typedef string::size_type pos;

	Screen() = default;
	Screen(pos ht, pos wd) :height(ht), width(wd) { }
	Screen(pos ht,pos wd,char c):height(ht),width(wd),contents(ht*wd,c) { }

	char get() const   //读取光标处的字符
	{
		return contents[cursor];  //隐式内联
	}
	inline char get(pos ht, pos wd) const; //显示内联

	Screen& move(pos r, pos c);  //负责移动光标,能在之后被设为内联

	Screen& set(char);
	Screen& set(pos r, pos col, char ch);

	Screen& display(ostream& os)
	{
		do_display(os);
		return *this;
	}
	const Screen& display(ostream& os) const
	{
		do_display(os);
		return *this;
	}


private:
	pos cursor = 0; //光标的位置
	pos height = 0, width = 0; //屏幕的宽高
	string contents; //存放数据
	//该函数负责显示Screen的内容
	void do_display(ostream& os) const
	{
		os << contents;
	}
};
char Screen::get(pos r, pos c) const
{
	pos row = r * width;
	return contents[row + c];
}
inline Screen& Screen::move(pos r, pos c) //内联,最好用这种方法,容易理解
{
	pos row = r * width;
	cursor = row + c;
	return *this;
}
inline Screen& Screen::set(char c)
{
	contents[cursor] = c; //设置当前光标所在位置的新值
	return *this; //将this对象作为左值返回
}
inline Screen& Screen::set(pos r, pos col, char ch)
{
	contents[r * width + col] = ch; //设置给定位置的新值
	return *this;  //将this对象作为左值返回
}

主程序

#include "screen.h"

int main()
{
	Screen myScreen(5, 5, 'x'); //创建一个有5*5个x的对象
	myScreen.move(4, 0).set('#').display(cout);//移动光标4*5+0下,把那个位置的x替换成#,并且显示出来
	cout << '\n';
	myScreen.display(cout);
	cout << '\n';
}

结果为:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值