栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ primer 14章习题答案

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ primer 14章习题答案

14.1节

练习14.1

相同点:对于优先级和结合型以及操作数的数目都不变。

不同点:重载操作符必须具有至少一个class或枚举类型的操作数。

14.2

//sales_data.h

#ifndef SALES_DATA_H
#define SALES_DATA_H
#include 
#include 
using namespace std;
class Sales_data
{
	friend void print(ostream &os,Sales_data rhs);
	friend istream& operator>>(istream &,Sales_data &rhs);
	friend ostream& operator<<(ostream &,const Sales_data &rhs);

	public:
		Sales_data() = default;
		Sales_data(const string &s):bookno(s){}
		Sales_data(const string &s,unsigned n,double r):
			bookno(s),cnt(n),revenue(r){}
		Sales_data(istream &is);

		const string & isbn()const
			{return bookno;}	
		
		Sales_data operator+(const Sales_data &rhs);
		Sales_data &operator+=(const Sales_data &rhs);


	private:
		unsigned cnt = 0;
		double revenue = 0.0;
		string bookno;
};
void print(ostream &os,Sales_data rhs);
istream& operator>>(istream &,const Sales_data &rhs);
ostream& operator<<(ostream &,const Sales_data &rhs);
#endif





//functions.cc
#include 
#include 
#include "sales_data.h"
using namespace std;

Sales_data & Sales_data::operator+=(const Sales_data &rhs)
{
if(this->bookno != rhs.bookno)
	throw runtime_error("Not same type.");
this->revenue += rhs.revenue;
this->cnt += rhs.cnt;
	return *this;
}	
Sales_data  Sales_data::operator+(const Sales_data &rhs)
{
if(this->bookno != rhs.bookno)
	throw runtime_error("Not the same type.");
Sales_data data;
data.bookno = rhs.bookno;
data.revenue = this->revenue + rhs.revenue;
data.cnt = this->cnt + rhs.cnt;
	return data;
}	


void print(ostream &os,Sales_data rhs)
{
os <<"bookno:"<>(istream &is,Sales_data &rhs)
{
is >> rhs.bookno >> rhs.cnt >> rhs.revenue;
return is;
}
ostream& operator<<(ostream &os,const Sales_data &rhs)
{
os << rhs.bookno << rhs.cnt << rhs.revenue;
return os;
}



//main.cc
#include 
#include 
#include "sales_data.h"
using namespace std;
int main()
{
Sales_data s1("book1",12,120);
Sales_data s2("book1",12,130);
s1 += s2;
Sales_data s3 = s1 + s2;
print(cout,s1);
print(cout,s3);
cout << "输入s1:" << endl;
cin >> s1;
cout << s1 << endl;
	return 0;
}
bookno:book1
	revenue:250
	cnt:24
bookno:book1
	revenue:380
	cnt:36
输入s1:
isbnabcdefg
12
120  
isbnabcdefg12120

14.2

(a) 应用了c++内置版本的==,比较两个指针。

(b)应用了svec1[1] == svec2[0] 应用了string版本的重载==。

(c)应用了svec1 == svec2 应用了vector版本的重载==。

(d)svec1[0] == "stone"应用了 string版本的重载==,字符串字面知被转换为string。

14.3
答:

(a)%通常定义飞成员

(b)%=通常定义为成员,因为会改变对象的状态

(c)++通常定义为类成员,因为它会改变对象的状态。

(d)->必须定义为成员否则,否则编译器会报错。
(e)<<通常定义非成员。因为做操作数为输出流,如果定义成成员,那就不符合<<的本来内置习惯。

(f)&&通常是定义成非成员

(g)==通常定义为非成员(操作符具有对称性一般定义为非成员,这样才可以必要时候转换,成员不能转换,左边操作数是确定的)

(h)()必须定义为成员,否则编译器会报错。

总结:

赋值=、下标[]、成员->、成员()这四个是必须定义成成员函数的。

复合的运算符一般定义成成员,但是不是必须。

改变对象状态的运算符(++,--)或者和对象有密切关系的运算符应该定义成成员函数,例如递增递减和解引用。

具有对称运算的运算符可能转换任意一端的运算对象,例如算数、关系、相等性和位运算符要定义成非成员运算符。

14.7

类内声明

friend ostream & operator<<(ostream & ,const String &rhs);

类外声明:

ostream & operator<<(ostream & ,const String &rhs);

最后源文件中定义:

ostream & operator<<(ostream &os,const String &rhs)
{
for(auto p = rhs.elements; p != rhs.first_free; ++p)
	{
	os << *p;	
	}
    return os;
}

补充和理解:

这里定义==和!=一定注意,如果类中有唯一一个动态内存,比如说strblobptr,当wptr都非空时候才比较curr,如果wptr都空时不必比较curr。也就是含有动态内存的类,比较的时候可能变量要分级对待(分级是我自己发明的说话,也就是说当内存都是nullptr时候,不必比较其它变量,也就是变量中间有级别的有限性,某些情况下,某个或者某些变量不必参与比较)。

14.2.2

14.3

14.3.1练习答案,这个答案产生一个疑问?两个StrBlob相等,到底是应该是data内的内容相等?还是data应该指向同一个vector?答案是比较了StrBlob的data的

 bool operator==(const StrBlob & lhs,const StrBlob &rhs)
{
	return (*(lhs.data) == *(rhs.data));
}

14.3.2节练习

14.18

friend声明和函数原型声明就略去了。看下面的定义:

//strblob.h中的

bool operator==(const StrBlob &lhs,const StrBlob & rhs)
{
	return lhs.data == rhs.data;
}
bool operator<(const StrBlob &lhs,const StrBlob &rhs)
{
	return *(lhs.data) < *(rhs.data);

}
bool operator>(const StrBlob &lhs,const StrBlob &rhs)
{
        return *(lhs.data) > *(rhs.data);

}

bool operator<=(const StrBlob &lhs,const StrBlob &rhs)
{
return *(lhs.data) <= *(rhs.data);

}
bool operator>=(const StrBlob &lhs,const StrBlob &rhs)
{
return *(lhs.data) >=*(rhs.data);

}

说明:就是比较两个strblob对象是否指向同一个data,如果是则正确,如果否,那么不想等。

strblobptr类:

bool operator== (const StrBlobPtr &lhs,const StrBlobPtr &rhs)
{
if(lhs.wptr.lock() == rhs.wptr.lock())
	{
//用auto l = lhs.wptr.lock() r = rhs.wptr.lock(),然后比较看起来更舒服
	return !lhs.wptr.lock() || lhs.curr == rhs.curr;
	}
else
	{
	return false;	
	}

}
bool operator!= (const StrBlobPtr &lhs,const StrBlobPtr &rhs)
{
	return !(lhs == rhs);
}


bool operator> (const StrBlobPtr&,const StrBlobPtr&)
{
	
}
bool operator< (const StrBlobPtr&,const StrBlobPtr&)
{


}
bool operator>= (const StrBlobPtr&,const StrBlobPtr&)
{



}
bool operator<= (const StrBlobPtr&,const StrBlobPtr&)
{



}

这里含有动态内存,动态内存wptr和变量,如果在动态内存wptr为空的时候(两个动态内存相等的情况下),比较curr的大小是无意义的。所以这里wptr和curr不是同一个级别的变量。作用的大小也是不对等的。

string.h

bool operator==(const String &lhs,const String &rhs)
{
if(lhs.size() != rhs.size())
	return false;

	for(auto ptr1  = lhs.begin(),ptr2 = rhs.begin();
		ptr1 != lhs.end() && ptr2 != rhs.end(); ++ ptr1,++ptr2)
		{
			if(*ptr1 != *ptr2)
				return false;	
		}
return true;
}
bool operator!=(const String &lhs,const String &rhs)
{
return !(lhs == rhs);

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/290290.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号