C++primer14章习题
来源:互联网 发布:毕业找不到工作知乎 编辑:程序博客网 时间:2024/04/29 20:07
//14.1在什么情况下重载操作符与内置操作符不同?在什么情况下重载操作符与内置操作符相同?
/*重载操作符与内置操作符的不同之处在于:重载操作符必须具有至少一个类类型或枚举类型的操作数:
重载操作符不保证操作数的求值顺序,例如“短路特性”
重载操作符与内置操作符的相同之处在于:操作符的优先级结合性及操作数数目均相同。*/
//14.2为Sales_item编写输入、输出、加以及复合赋值操作符的重载声明
#include<iostream>
classSales_item{
friend std::ostream& operator<<(std::ostream&, Sales_item&);
friend std::istream& operator>>(std::istream&, Sales_item&);
public:
Sales_item&operator+= (constSales_item&);
};
Sales_itemoperator+(const Sales_item&,const Sales_item&);
//14.3解释如下程序,假定接受一个string参数的Sales_item构造函数不为explicit。解释如果该构造函数为explicit会怎样
string numm_book ="9-999-99999-9";
Sales_item item(cin);
item += null_book;
//如果不是explicit那null_book会转换成Sales_item然后完成operator+吧
//如果是explicit那就没这回事了。
//14.4string额vector类都定义了一个重载的==,可用于比较这些类的对象,指出下面的表达式中应用了哪个==版本。
string s;
vector<string> svec1, svec2;
"cobble"=="stone"; //内置==版本
svec1[0] == svec2[0]; //string==版本
svec1 == svec2; //vector==版本
//14.5列出必须定义为类成员的操作符
//赋值=,下标[],调用(),成员访问箭头->
//14.6解释下面操作符是否应该为类成员,为什么
//+,<<,==操作符通常应定义为非成员函数,但<<操作符通常需要访问类的数据成员,所以一般应指定为类的友元
//+=和++会改变对象的状态,通产应定义为类成员
//->和()必须定义为类成员,否则会出现编译错误
//&&一般对类类型操作数没有意义,通常不进行重载;如果一定要重载,可重载为非成员函数
//14.7为下面的CheckoutRecord类定义一个输出操作符:
#include<iostream>
#include<string>
#include<utility>
#include<vector >
structDate{
int year;
int month;
};
classCheckoutRecord{
friend std::ostream& operator<<(std::ostream&,const CheckoutRecord&);
public:
private:
double book_id;
std::stringtitle;
Datedate_borrowed;
Datedate_due;
std::pair<std::string,std::string> borrower;
std::vector<std::pair<std::string, std::string>* > wait_list;
};
std::ostream&operator<< (std::ostream& out, const CheckoutRecord& obj)
{
out<< obj.book_id << obj.title << obj.date_borrowed.month<< obj.date_borrowed.year
<<obj.date_due.month << obj.date_due.year << std::endl;
out<< obj.borrower.first <<"\t"<< obj.borrower.second << std::endl;
for(std::vector< std::pair<std::string,std::string>* >::const_iterator beg(obj.wait_list.begin());
beg!= obj.wait_list.end(); beg++)
out<< (*beg)->first << (*beg)->second;
return out;
}
//14.8 12.4节的习题中,你编写了下面某个类的框架为所选择的的类编写输出操作符
#include<iostream>
classBook{
friend std::ostream& operator<<(std::ostream&,const Book&);
public:
private:
};
std::ostream&operator<< (std::ostream& out, const Book& obj)
{
//do sth
return out;
}
//14.9给定下述输入,描述Sales_item输入操作符的行为
// 0-201-9999 10 24.95
// 10 24.94 0-201-9999
#include<iostream>
#include<string>
classSales_item{
friend std::istream& operator>>(std::istream&, Sales_item&);
private:
std::stringisbn;
double price;
int n;
};
std::istream&operator>> (std::istream& in,Sales_item& obj)
{
in>> obj.isbn >> obj.price >> obj.n;
if(!in)
{
std::cout<<"error";
obj = Sales_item();
}
return in;
}
intmain()
{
Sales_itemobj;
std::cin>> obj;
return 0;
}
//14.10下述Sales_item输入操作符有什么错误
std::istream&operator>> (std::istream& in,Sales_item& s)
{
double price;
in>> s.isbn >> s.units_sold >> price;
s.revenue= s.units_sold * price;
return in;
}
//没有对输入失败的情况进行处理,从而导致对象可能处于不一致的状态。
//14.11 14.2.1节习题中定义的CheckoutRecord类定义一个输入操作符,确保该操作符处理输入错误。
#include<iostream>
#include<string>
#include<utility>
#include<vector >
structDate{
int year;
int month;
};
classCheckoutRecord{
friend std::ostream& operator<<(std::ostream&,const CheckoutRecord&);
friend std::istream& operator>>(std::istream&, CheckoutRecord&);
public:
private:
double book_id;
std::stringtitle;
Datedate_borrowed;
Datedate_due;
std::pair<std::string,std::string> borrower;
std::vector<std::pair<std::string, std::string>* > wait_list;
};
std::ostream&operator<< (std::ostream& out, const CheckoutRecord& obj)
{
out<< obj.book_id << obj.title << obj.date_borrowed.month<< obj.date_borrowed.year
<<obj.date_due.month << obj.date_due.year << std::endl;
out<< obj.borrower.first <<"\t"<< obj.borrower.second << std::endl;
for(std::vector< std::pair<std::string,std::string>* >::const_iterator beg(obj.wait_list.begin());
beg!= obj.wait_list.end(); beg++)
out<< (*beg)->first << (*beg)->second;
return out;
}
std::istream&operator>> (std::istream& in,CheckoutRecord& obj)
{
in>> obj.book_id >> obj.title
>>obj.borrower.first >> obj.borrower.second
>>obj.date_borrowed.month >> obj.date_borrowed.year
>>obj.date_due.month >> obj.date_due.year;
if(!in)
{
std::cout<<"error";
return in;
}
obj.wait_list.clear();
while(in)
{
std::pair<std::string,std::string>* ppa =new std::pair<std::string,std::string>;
in>> ppa->first >> ppa->second;
if(!in)
return in;
obj.wait_list.push_back(ppa);
}
return in;
}
//14.12编写Sales_item操作符,用+进行实际加法,而+=调用+。与本节中操作符的实现方法相比较,讨论这个方法的缺点
classSales_item{
friendSales_itemoperator+ (constSales_item&,const Sales_item&);
public:
Sales_item&operator+= (constSales_item&);
private:
int data;
};
Sales_itemoperator+(const Sales_item& a,constSales_item& b)
{
Sales_itemsum;
sum.data= a.data + b.data;
return sum;
}
Sales_item& Sales_item::operator+= (constSales_item& rhs)
{
Sales_itemsum(*this + rhs);
*this = sum;
return *this;
}
//缺点,这样的+=效率低,需要创建和撤销一个临时Sales_item对象来保存+操作的结果,不如本节中给出的操作符实现方法简单有效。
//14.13如果有,你认为Sales_item还应该支持哪些其他算数操作符?定义你认为该类应包含的那些。
#include<iostream>
classSales_item{
friend Sales_item operator-(const Sales_item&,const Sales_item&);
public:
Sales_item&operator-= (constSales_item&);
private:
int price;
};
Sales_item& Sales_item::operator-= (constSales_item& rhs)
{
price-= rhs.price;
return *this;
}
Sales_itemoperator-(const Sales_item& lhs,const Sales_item& rhs)
{
Sales_itemsum(lhs);
sum-= rhs;
return sum;
}
//14.14定义一个赋值操作符,将isbn赋值给Sales_item对象
Sales_item& Sales_item::operator= (conststd::string rhs)
{
isbn= rhs;
return *this;
}
//14.15为.2.1节习题中介绍的CheckoutRecord类定义赋值操作符
CheckoutRecord& CheckoutRecord::operator= (constCheckoutRecord& rhs)
{
book_id= rhs.book_id;
title= rhs.title;
date_borrowed= rhs.date_borrowed;
date_due= rhs.data_due;
wait_list.clear();
for(vector< pair<string, string>*>::const_iterator beg(rhs.wait_list.begin());
beg!= rhs.wait_list.end(); beg++)
{
pair<string,string>* ppa =new pair<string,string>;
*ppa= **beg;
wait_list.push_back(ppa);
}
return *this;
}
//14.16CheckoutRecord类还应该定义其他赋值操作符吗?如果是,解释哪些类型应该用作操作数并解释为什么,为这些类型实现赋值操作符
CheckoutRecord& CheckoutRecord::operator= (constDate& new_due)
{
date_due= new_due;
return *this;
}
CheckoutRecord& CheckoutRecord::operator= (conststd::pair<string, string>& awaiter)
{
pair<string,string>*ppa =new pair<string,string>;
*ppa= awaiter;
wait_list.push_back(ppa);
return *this;
}
//14.17 14.2.1节习题中定义了一个CheckoutRecord类,为该类定义一个下标操作符,从等待列表中返回一个名字
pair<string, string>&CheckoutRecord::operator[] (const vector< pair<string, string>*>::size_type index)
{
return *wait_list.at[index];
}
constpair<string, string>& CheckoutRecord::operator[](const vector< pair<string, string>*>::size_type index) const
{
return *wait_list.at[index];
}
//14.18讨论用下标操作符实现这个操作的优缺点
//优点:使用简单
//缺点:语义不够清楚。下标操作符适合于表示“获取容器中的元素”这一语义,此处的CheckoutRecord对象并不是一个通常意义上的容器
// 而“等待着”更不是“CheckoutRecord容器中的一个元素”,因此使用下标操作符不能清楚的表示“获得一个等待者”这一应用语义。
//14.19提出另一种方法定义这个操作
//可将这个操作定义为普通的成员函数,例如
//pair<string,string>& get_awaiter(const size_t index)及
// constpair<string,string>& get_awaiter(const size_t index) const
//14.20在ScreenPtr类的概略定义中,声明但没有定义赋值操作符。请实现ScreenPtr赋值操作符。
//14.22智能指针可能应该定义相等操作符和不等操作符,以便测试两个指针是否相等或不等,将这些操作加入到ScreenPtr类。
classScreen{};
classScrPtr{
friend classScreenPtr;
private:
ScrPtr(Screen*p):sc(p){}
int use;
Screen*sc;
};
classScreenPtr{
friend bool operator== (constScreenPtr&, const ScreenPtr&);
friend bool operator!= (constScreenPtr&, const ScreenPtr&);
public:
ScreenPtr(Screen*p):ptr(new ScrPtr(p)){}
ScreenPtr(const ScreenPtr& orig):
ptr(orig.ptr){++ptr->use;}
~ScreenPtr(){--ptr->use;}
ScreenPtr&operator= (constScreenPtr&);
private:
ScrPtr*ptr;
};
//定义赋值操作符
ScreenPtr& ScreenPtr::operator= (constScreenPtr& rhs)
{
++rhs.ptr->use;
if(--ptr->use == 0)
delete ptr;
ptr= rhs.ptr;
return *this;
}
//定义==操作符
booloperator== (constScreenPtr& lhs,const ScreenPtr& rhs)
{
return lhs.ptr == rhs.ptr;
}
booloperator!= (constScreenPtr& lhs,const ScreenPtr& rhs)
{
return !(lhs == rhs);
}
//14.21定义一个类,该类保存一个指向ScreenPtr的指针,为该类定义一个重载的箭头操作符。
classpSPtr{
public:
Screen*operator->();
Screen*operator->()const;
private:
ScreenPtr*p;
};
Screen* pSPtr::operator->()
{
return p->ptr->sp;
}
constScreen* pSPtr::operator->()const
{
return p->ptr->sp;
}
//14.23CheckedPtr类表示指向数组的指针,为该类重载下标操作符和解引用操作符。使操作符确保CheckedPtr有效:它应该不可能对超出数组末端的元素进行解引用或索引。
//14.24是否应该对下标操作符参数为负数进行检查
//哎,又没想到
//14.25定义相等和关系操作符
//14.26为CheckedPtr类定义加法或剪发,以便这些操作符实现指针运算。
#include<stdexcept>
classCheckedPtr{
friend bool operator==(constCheckedPtr&, const CheckedPtr&);
friend bool operator!=(constCheckedPtr&, const CheckedPtr&);
friend bool operator>(constCheckedPtr&, const CheckedPtr&);
friend bool operator<(constCheckedPtr&, const CheckedPtr&);
friend bool operator>=(constCheckedPtr&, const CheckedPtr&);
friend bool operator<=(constCheckedPtr&, const CheckedPtr&);
friend int operator+(constCheckedPtr&, const CheckedPtr&);
friend int operator-(constCheckedPtr&, const CheckedPtr&);
friend CheckedPtr operator+(const CheckedPtr&,constint);
friend CheckedPtr operator-(const CheckedPtr&,constint);
public:
CheckedPtr(int *b,int *e):beg(b), cur(b), end(e){}
CheckedPtr(const CheckedPtr &rhs):beg(rhs.beg),end(rhs.end), cur(rhs.cur){}
CheckedPtr&operator++();
CheckedPtroperator++(int);
CheckedPtr&operator--();
CheckedPtroperator--(int);
int& operator[](constint);
const int& operator[](const int)const ;
int& operator*();
const int& operator*()const;
private:
bool range_equal(constCheckedPtr &rhs)const
{return beg==rhs.beg && end==rhs.end;} //答案说需要判断区间相同,我觉得不判断也行,而且答案给的代码是有问题的
int *cur;
int *beg;
int *end;
};
CheckedPtr& CheckedPtr::operator++()
{
if(cur == end)
throw std::out_of_range("incrementpast the end of CheckedPtr");
++cur;
return *this;
}
CheckedPtr CheckedPtr::operator++(int)
{
CheckedPtrret(*this);
++*this;
return ret;
}
CheckedPtr& CheckedPtr::operator--()
{
if(cur == beg)
throw std::out_of_range("decrementpast the beginning of CheckedPtr");
--cur;
return *this;
}
CheckedPtr CheckedPtr::operator--(int)
{
CheckedPtrret(*this);
--*this;
return ret;
}
int&CheckedPtr::operator *()
{
if(cur == end)
throw std::out_of_range("invalidcurrent pointer");
return *cur;
}
constint& CheckedPtr::operator*()const
{
if(cur == end)
throw std::out_of_range("invalidcurrent pointer");
return *cur;
}
int&CheckedPtr::operator[] (int index)
{
if(beg+index >= end || beg+index < beg)
throw std::out_of_range("outof range");
return *(beg+index);
}
constint& CheckedPtr::operator[](int index)const
{
if(beg+index >= end || beg+index < beg)
throw std::out_of_range("outof range");
return *(beg+index);
}
booloperator== (constCheckedPtr &lhs,const CheckedPtr &rhs)
{
return lhs.range_equal(rhs) && lhs.cur ==rhs.cur;
}
booloperator!= (constCheckedPtr &lhs,const CheckedPtr &rhs)
{
return lhs.range_equal(rhs) && !(lhs == rhs);
}
booloperator> (constCheckedPtr &lhs,const CheckedPtr &rhs)
{
return lhs.range_equal(rhs) && lhs.cur >rhs.cur;
}
booloperator>= (constCheckedPtr &lhs,const CheckedPtr &rhs)
{
return lhs.range_equal(rhs) && !(lhs <rhs);
}
booloperator< (constCheckedPtr &lhs,const CheckedPtr &rhs)
{
return lhs.range_equal(rhs) && lhs.cur <rhs.cur;
}
booloperator<= (constCheckedPtr &lhs,const CheckedPtr &rhs)
{
return lhs.range_equal(rhs) && !(lhs >rhs);
}
intoperator+ (constCheckedPtr &lhs,const CheckedPtr &rhs)
{
if(!lhs.range_equal(rhs))
throw std::out_of_range("can'tsubstract");
return rhs.cur - lhs.cur;
}
intoperator- (constCheckedPtr &lhs,const CheckedPtr &rhs)
{
if(!lhs.range_equal(rhs))
throw std::out_of_range("can'tsubstract");
return rhs.cur - lhs.cur;
}
CheckedPtroperator+(const CheckedPtr& lhs,const int index)
{
if(lhs.cur+index > lhs.end)
throw std::out_of_range("outof range");
CheckedPtrret(lhs);
ret.cur+= index;
return ret;
}
CheckedPtroperator-(const CheckedPtr &lhs,const int index)
{
if(lhs.cur-index < lhs.beg)
throw std::out_of_range("outof range");
CheckedPtrret(lhs);
ret.cur-= index;
return ret;
}
//14.27讨论允许将空数组实参传给CheckedPtr构造函数打而有优缺点
//优点:构造函数的定义简单
//缺点:导致所构造的checkedPtr对象有可能没有指向有效的数组,从而失去其使用价值。比较完善的实现方法应该在构造函数中对参数进行检查(保证beg<end)。
//14.28没有定义自增和自减操作符的const版本,为什么
//以为内对const对象不能使用自增和自减操作符
//14.29我们也没有实现箭头操作符,而为什么
//因为该CheckedPtr类所指向的是int型数组,int型为内置类型,没有显示定义的成员函数,
//所以不需要通过CheckedPtr对象使用箭头操作符来访问int对象的成员,也无需为CheckedPtr类定义箭头操作符
//14.30定义一个CheckedPtr版本,保存Screen数组,为该类实现重载的自增,自减,解引用和箭头等操作符
#include<stdexcept>
classScreen{};
classCheckedPtr{
public:
CheckedPtr(Screen*b, Screen *e):beg(b), end(e), curr(b){}
Screen&operator*();
const Screen& operator*()const;
CheckedPtr&operator++();
CheckedPtr&operator--();
CheckedPtroperator++(int);
CheckedPtroperator--(int);
Screen*operator->();
const Screen* operator->()const;
private:
Screen*beg;
Screen*end;
Screen*curr;
};
Screen& CheckedPtr::operator*()
{
if (curr == end)
throw std::out_of_range("invalidcurrent pointer");
return *curr;
}
constScreen& CheckedPtr::operator*()const
{
if (curr == end)
throw std::out_of_range("invalidcurrent pointer");
return *curr;
}
CheckedPtr& CheckedPtr::operator++()
{
if (curr == end)
throw std::out_of_range("incrementpast the end of CheckedPtr");
++curr;
return *this;
}
CheckedPtr CheckedPtr::operator++(int)
{
if (curr == end)
throw std::out_of_range("incrementpast the end of CheckedPtr");
CheckedPtrret(*this);
++curr;
return ret;
}
CheckedPtr& CheckedPtr::operator--()
{
if (curr == beg)
throw std::out_of_range("decrementpast the beginning of CheckedPtr");
--curr;
return *this;
}
CheckedPtr CheckedPtr::operator--(int)
{
if (curr == beg)
throw std::out_of_range("decrementpast the beginning of CheckedPtr");
CheckedPtrret(*this);
--curr;
return ret;
}
Screen* CheckedPtr::operator->()
{
return curr;
}
constScreen* CheckedPtr::operator->()const
{
return curr;
}
//14.31定义一个函数对象执行“如果则否则”操作
template<typename T>
classNoName{
public:
Toperator() (constT a,const T b,constT c)
{
return a ? b : c;
}
};
//14.32一个重载的函数调用操作符可以接受多少个操作数
//与函数调用可以接受的操作数一样,为个或多个。
//14.33使用标准库算法和GT_cls类,编写一个程序查找序列中第一个比指定之大的元素。
#include<algorithm>
#include<iostream>
#include<vector>
usingnamespace std;
classGT_cls{
public:
GT_cls(int i = 0):num(i){}
bool operator() (constint &test)
{
return test > num;
}
private:
int num;
};
intmain()
{
vector<int> vec;
cout<<"请输入数组元素" << endl;
int data;
while (cin >> data)
vec.push_back(data);
cin.clear();
cout<<"请输入查找元素" << endl;
cin>> data;
vector<int>::iterator find = find_if(vec.begin(),vec.end(), GT_cls(data));
if (find != vec.end())
cout<< *find << endl;
else cout << "noelement that is larger than " << endl;
}
//14.34编写类似于GT_cls的函数对象类,但测试两个值是否相等。使用该对象和标准库算法编写程序,替换序列中给定值的所有实例。
#include<iostream>
#include<algorithm>
#include<vector>
usingnamespace std;
classGT_cls{
public:
GT_cls(int i = 0):spValue(i){}
bool operator() (constint &ival)
{
return ival == spValue;
}
private:
int spValue;
};
intmain()
{
vector<int> vec;
cout<<"请输入数据" << endl;
int data;
while (cin >> data)
vec.push_back(data);
cin.clear();
cout<<"请输入要替换的数据和替换值" << endl;
int replacedVal, newVal;
cin>> replacedVal >> newVal;
replace_if(vec.begin(),vec.end(), GT_cls(replacedVal), newVal);
for(vector<int>::iteratorbeg(vec.begin()); beg != vec.end(); ++beg)
cout<< *beg << endl;
return 0;
}
//14.35编写类似于GT_cls的类,但测试给定string对象的长度是否与其边界相匹配。使用该对象重写.2.3节中的程序,以便报告输入中有多少单词的长度在到之间
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<fstream>
usingnamespace std;
classGT_cls{
public:
GT_cls(int min,int max):
minLength(min), maxLength(max){}
bool operator() (const string &str)
{
return str.length() >= minLength &&str.length() <= maxLength;
}
private:
int minLength;
int maxLength;
};
boolisShorter(const string &s1,const string &s2)
{
return s1.length() < s2.length();
}
intmain()
{
ifstreamin("1.txt");
stringstr;
vector<string>vec;
while (in >> str)
vec.push_back(str);
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()), vec.end());
stable_sort(vec.begin(),vec.end(), isShorter);
vector<string>::size_typecount = count_if(vec.begin(), vec.end(), GT_cls(1,10));
cout<< count << endl;
vector<string>::iteratorbeg = find_if(vec.begin(), vec.end(), GT_cls(1,10));
while(beg != vec.end())
{
cout<< *beg <<" "<<endl;
beg= find_if(++beg, vec.end(), GT_cls(1,10));
}
cout<< endl;
return 0;
}
//14.36修改前一程序以报告长度在1到9之间以及10以上的单词的数目。
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<fstream>
usingnamespace std;
classGT_cls{
public:
GT_cls(int min,int max):
minLength(min), maxLength(max){}
bool operator() (const string &str)
{
return str.length() >= minLength &&str.length() <= maxLength;
}
private:
int minLength;
int maxLength;
};
boolisShorter(const string &s1,const string &s2)
{
return s1.length() < s2.length();
}
intmain()
{
ifstreamin("1.txt");
stringstr;
vector<string>vec;
while (in >> str)
vec.push_back(str);
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()), vec.end());
stable_sort(vec.begin(),vec.end(), isShorter);
vector<string>::size_typecount = count_if(vec.begin(), vec.end(), GT_cls(1,9));
cout<< count << endl;
//统计以上
count= count_if(vec.begin(), vec.end(), GT_cls(10,0xffff));
cout<< count << endl;
return 0;
}
//14.37使用标准库函数对象和函数适配器,定义一个对象用于
//a查找大于的所有值
//b查找不等于pooh的所有字符串
//c将所有值乘以
#include<functional>
#include<iostream>
#include<string>
#include<fstream>
#include<vector>
#include<algorithm>
usingnamespace std;
intmain()
{
ifstreamin("1.txt");
vector<int> vec;
int data;
while (in >> data)
vec.push_back(data);
cout<<"大于的" << endl;
vector<int>::iterator cur = find_if(vec.begin(),vec.end(), bind2nd(greater<int>(),1024));
while (cur != vec.end())
{
cout<< *cur <<" ";
cur= find_if(++cur, vec.end(), bind2nd(greater<int>(),1024));
}
cout<< endl;
cout<<"不等于pooh的"<< endl;
vector<string>vec2;
stringstr;
in.clear();
in.close();
in.open("1.txt");
while (in >> str)
vec2.push_back(str);
vector<string>::iteratorpstr = find_if(vec2.begin(), vec2.end(), not1(bind2nd(equal_to<string>(),"pooh")));
while (pstr != vec2.end())
{
cout<< *pstr <<" ";
pstr= find_if(++pstr, vec2.end(), not1(bind2nd(equal_to<string>(),"pooh")));
}
cout<< endl;
cout<<"乘以以后" << endl;
transform(vec.begin(),vec.end(), vec.begin(), bind2nd(multiplies<int>(),2));
for (vector<int>::iteratorit(vec.begin()); it != vec.end(); it++)
cout<< *it <<" ";
cout<< endl;
return 0;
}
//14.38最后一个count_if调用中,用not1将bind2nd(less_equal<int>(),10)的结果求反,为什么使用not1而不用not2
//not1用于将一元函数对象的真值求反,not2用于将二元函数对象的真值求反,函数适配器bind2nd将less_equal对象的右操作数绑定到,从而
//将less_equal对象由二元函数对象转换为一元函数对象,所以只能用not1对bind2nd(less_equal<int>(), 10))的结果进行求反
//14.39使用标准库函数对象代替GT_cls来查找指定长度的单词
#include<functional>
#include<fstream>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
usingnamespace std;
intmain()
{
ifstreamin("1.txt");
vector<string>vec;
stringstr;
while (in >> str)
vec.push_back(str);
in.clear();
cout<<"输入要查找的长度值" << endl;
int length;
cin>> length;
int count(0);
equal_to<int> equ;
for (vector<string>::iterator beg(vec.begin());beg != vec.end(); beg++)
if(equ(beg->length(),length))
count++;
cout<< count << endl;
}
//14.40编写可将Sales_item对象转换为string类型和double类型的操作符。你认为这些操作符应返回什么值?
//你认为定义这些操作符是个好办法吗?解释你的结论
Sales_item::operatorstring()const
{
return isbn;
}
Sales_item::operatordouble()const
{
return price;
}
//定义这些操作符并不是个好办法,因为一般不必在需要string类型和double类型对象的地方使用Sales_item对象,这种用法意义不大
//14.41解释这两个转换操作符之间的不同
//这两个转换操作符是否太严格了?如果是,怎样使得转换更通用一些?
classIntegral{
public:
operator const int() const;
operator int() const;
};
//一个将Integral对象转换为constint,另一个将Integral对象转换为int
//是,去掉operator const int() const;即可
//事实上,如果这两个转换操作符同时存在,则在既可使用int型const变量又可使用int型变量的情况下,会因编译器无法做出抉择而产生错误。
//14.42为.2.1节习题中的CheckoutRecord类定义到bool的转换操作符
CheckoutRecord::operatorbool()const
{
return wait_list.empty();
}
//14.43解释bool转换操作符做了什么。这是这个CheckoutRecord类型转换唯一可能的含义吗?
//解释你是否认为这个转换是一种转换操作的良好使用。
//这个操作将CheckoutRecord对象转换为bool进行判断。具体的情景忘了= =
//14.44为下述每个初始化列出可能的类类型的转换序列。每个初始化的结果是什么?
clss LongDouble{
public:
operator double();
operator float();
};
LongDouble ldObj;
//a int ex1 = ldObj; 有二义性:因为两者都可以转换为int,二者无优劣之分
//b float ex2 = ldObj; 从LongDouble到float的转换操作,将ldObj对象转换为float值用于初始化ex2
//14.45哪个calc()函数是如下函数调用的最佳可行函数?列出调用每个函数所需的转换序列,并解释为什么所选定的就是最佳可行函数
classLongDouble{
public:
LongDouble(double);
};
voidcalc(int);
voidclac(LongDouble);
doubleval;
calc(val);
//最佳可行函数为void calc(int)
//调用void calc(int)所需的转换为,将实参val由double类型转换为int类型(标准转换)
//调用void calc(LongDoubles)所需的转换为:将实参val由double类型转换为LongDouble类型(使用LongDouble类的构造函数,为类类型转换)
//因为标准转换优于类型转换,所以void calc(int)为最佳可行函数
//14.46对于main中的加操作,哪个operator+是最佳可行函数?列出候选函数、可行函数以及对每个可行函数中实参的类型转换
classComplex{
public:
Complex(double);
};
classLongDouble{
friend LongDouble operator+(LongDouble&,int);
public:
LongDouble(int);
operator double();
LongDoubleoperator+(constComplex&);
};
LongDoubleoperator+(const LongDouble&,double);
LongDouble ld(16.08);
doubleres = ld + 15.05;
//①内置的+操作符
//②LongDouble operator+ (LongDouble&, int);(LongDouble类的友员)
//③LongDouble LongDouble::operator+(const Complex&);
//④LongDouble operator+(const LongDouble&, double);(全局变量)
//都是可行函数,因为④不需要类型转换,所以是最佳可行函数
- C++primer14章习题
- C++primer13章习题
- C++primer15章习题
- 【C】第四章习题
- c++primer第二章习题
- C++primer 第二章习题
- C++Primer第三章习题
- C++Primer第五章习题
- c++primer 第十章习题
- C++primer第二章习题
- C++Primer习题第四章
- C++primer习题第五章
- C++Primer习题第六章
- C++Primer习题第七章
- C++primer习题第八章
- C++Primer习题第九章
- C++Primer习题第十一章
- C++Primer习题第十二章
- Maximum Depth of Binary Tree
- Same Tree
- C++primer13章习题
- C++primer13,14章总结
- 第一炮
- C++primer14章习题
- Vacation is coming. No update fora while
- C++primer15章总结
- C++primer15章习题
- 水编译的两天
- Leetcode (一)
- 被问到的问题
- Hashmat the brave warrior
- Back to High School Physics