C++Primer 第14章-重载操作符与转换-课后习题答案(3)

2019-03-16 18:02

22。智能指针可能应该定义相等操作符和不等操作符,以便测试两个指针是否相等或不等。将这些操作加入到ScreenPtr类。 class ScreenPtr {

public: // … friend inline bool operator==( const ScreenPtr &, const ScreenPtr &); friend inline bool operator!=( const ScreenPtr &, const ScreenPtr &); private: ScrPtr *ptr; };

// operator ==

inline bool operator==( const ScreenPtr &p1, const ScreenPtr &p2 ) { return p1.ptr == p2.ptr; }

// operator !=

inline bool operator!=( const ScreenPtr &p1, const ScreenPtr &p2 ) { return !( p1.ptr == p2-.ptr ); }

23。CheckedPtr 类表示指向数组的指针。为该类重载下标操作符和解引用操作符。使操作符确保CheckedPtr有效:它应该不可能对超出数组末端的元素进行解引用或索引。 // 下标操作符重载

int& CheckedPtr::operator[]( const size_t index ) { if ( beg + index >= end ) throw out_ot_range( “ invalid index“ ); return *( beg + index ); }

const int & CheckedPtr::operator[] ( const size_t index ) const { if ( beg + index >= end ) throw out_ot_range( “ invalid index“ ); return *( beg + index ); }

// 解引用操作符重载 int CheckedPtr::operator*() { if ( curr == end )

throw out_of_range( “ invalid current pointer” ); return *curr; }

const int& CheckedPtr::operator*() const { if ( curr == end ) throw out_of_range(“ invalid current pointer”); return *curr; }

24。习题14.23中定义的解引用操作符或下标操作符,是否也应该检查对数组起点之前的元素进行的解引用或索引?解释你的答案。

对于下标操作符,应该进行检查,因为当用户给出的下标索引值小于0时,编译器不会出现编译错误,而会出现运行时错误。应修改为: // 下标操作符重载

int& CheckedPtr::operator[]( const size_t index ) { if ( beg + index >= end || beg + index < beg ) throw out_ot_range( “ invalid index“ ); return *( beg + index ); }

const int & CheckedPtr::operator[] ( const size_t index ) const { if ( beg + index >= end || beg + index < beg ) throw out_ot_range( “ invalid index“ ); return *( beg + index ); }

而对于解引用操作符,返回curr所指向的数组元素,在创建对象时已经将curr初始化为指向数组的第一个元素,只有当执行—操作时才会对curr进行减的操作,而—操作符已经对curr的值与数组起点进行了检查,所以不用再在这里检查。

25。为了表现得像数组指针,CheckedPtr类应实现相等和关系操作符,以便确定两个CheckedPtr对象是否相等,或者一个小于另一个,诸如此类。为CheckedPtr类增加这些操作。 应将这些操作符声明为CheckedPtr的友元。 // 相等操作符

bool operator==( const CheckedPtr& lhs, const CheckedPtr& rhs ) { return lhs.beg == rhs.beg && lhs.end == rhs.end && lhs.curr == rhs.curr; }

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

// 关系操作符

bool operator<( const CheckedPtr & lhs, const CheckedPtr& rhs ) { return lhs.beg == rhs.beg && lhs.end == rhs.end && lhs.curr < rhs.curr; }

bool operator>( const CheckedPtr & lhs, const CheckedPtr& rhs ) { return lhs.beg == rhs.beg && lhs.end == rhs.end && lhs.curr > rhs.curr; }

bool operator<=( const CheckedPtr & lhs, const CheckedPtr& rhs ) { return !( lhs.curr > rhs.curr ); }

bool operator >=( const CheckedPtr & lhs, const CheckedPtr& rhs ) { return !( lhs.curr < rhs.curr ); }

26。为CheckedPtr类定义加法或减法,以便这些操作符实现指针运算。 将这两个操作符声明为类的友元。

CheckedPtr operator+( const CheckedPtr& lhs, const size_t n ) { CheckedPtr temp( lhs ); temp.curr += n; if ( temp.curr > temp.end ) throw out_of_range(“ Too large n, over.”); return temp; }

CheckedPtr operator-( const CheckedPtr& lhs, const size_t n ) { CheckedPtr temp( lhs ); temp.curr -= n; if ( temp.curr < temp.beg ) throw out_of_range(“ Too large n, over.”); return temp; }

用到了复制构造函数,定义为:

CheckedPtr::CheckedPtr( const CheckedPtr& cp ): beg( cp.beg ), end( cp.end ), curr( cp.curr ) { }

27。讨论允许将空数组实参传给CheckedPtr构造函数的优缺点。

优点:构造函数的定义简单。缺点:导致构造的对象没有指向有效的数组,从而失去使用价值。应该在构造函数里控制参数确保beg

28。没有定义自增和自减操作符的const版本,为什么?

const所修饰的operator,不可以改变对象,而自增和自减肯定改变了对象,与const意义相反,所以不定义const版本。

29。我们也没有实现箭头操作符,为什么?

因为此类所指向的是int型数组,int型为内置类型,而箭头操作符必须返回一个类类型的指针,所以不实现。

30。定义一个CheckedPtr版本,保存Screen数组。为该类实现重载的自增、自减。解引用和箭头等操作符。 class CheckedPtr {

public: CheckedPtr( Screen *b, Screen *e ): beg( b ), end( e ), curr( b ) { }

// 自增、自减

CheckPtr& operator++(); CheckPtr& operator—(); CheckPtr& operator++( int ); CheckPtr& operator—( int ); // 箭头操作符

Screen* operator->();

const Screen* operator->() const;

// 解引用操作 Screen& operator*(); const Screen& operator*(); private: Screen *beg; Screen *end; Screen *curr; };

CheckPtr& CheckPtr::operator++() { if ( curr == end ) throw out_of_range( “increment past the end of CheckedPtr”); ++curr;

return *this; }

CheckPtr& CheckPtr::operator—() { if ( curr == begin ) throw out_of_range( “decrement past the beginning of CheckedPtr”); --curr; return *this; }

// 后缀式

CheckPtr& CheckPtr::operator++( int ) { CheckedPtr temp( *this ); ++*this; return temp; }

CheckPtr& CheckPtr::operator—( int ) { CheckedPtr temp( *this ); --*this; return temp; }

// 箭头操作符

Screen* CheckedPtr::operator->() { return curr; }

const Screen* CheckedPtr::operator->() const { return curr; }

Screen& CheckedPtr::operator*() { if ( curr == end ) throw out_of_range( “invalid current pointer.”); return *curr; }

const Screen& CheckedPtr::operator*() const { if ( curr == end ) throw out_of_range( “invalid current pointer.”); return *curr; }


C++Primer 第14章-重载操作符与转换-课后习题答案(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2013北京大兴区高三数学(文)一模试题及答案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: