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);(全局变量)

//都是可行函数,因为不需要类型转换,所以是最佳可行函数

0 0
原创粉丝点击