您的位置:首頁>正文

程式設計語言C/C++基礎知識詳解——自增/自減操作符

引言:

自增, 自減操作符經常由諸如反覆運算器這樣的類實現, 這樣的類提供類似于指標的行為來訪問序列中的元素。 例如, 可以定義一個類, 該類指向一個陣列並為該陣列中的元素提供訪問檢查:

1、定義自增/自減操作符

【最佳實踐】

C++語言不要求自增/自減操作符一定作為類的成員, 但是, 因為這些操作符改變操作物件的狀態, 所以更傾向于將它們作為成員!

2、定義前自增/自減操作符

首碼式操作符的聲明看起來像這樣:

class CheckedPtr

{

public:

CheckedPtr &operator++();

CheckedPtr &operator--();

//AS Before

};

【最佳實踐】

為了與內置類型一致, 首碼操作符應該返回被增量或減量對象的引用。

自增操作符根據end檢查curr,從而確保用戶不能將curr增加到超過陣列的末端。 自減操作將curr減 1並檢查是否會減到beg,如果curr增量到超過end或curr自減超過 beg就拋出一個out_of_range異常:

CheckedPtr &CheckedPtr::operator++()

{

if (curr == end)

{

throw out_of_range("increment past the end of CheckedPtr");

}

++ curr;

return *this;

}

CheckedPtr &CheckedPtr::operator--()

{

if (curr == beg)

{

throw out_of_range("decrement past the beginning of CheckedPtr");

}

-- curr;

return *this;

}

3、區別操作符的首碼和尾碼形式

尾碼式操作符函數接受一個額外的(即:無用的)int型形參。 使用尾碼式操作符時,

編譯器提供0作為這個形參的實參。 這個int形參的唯一目的就是使尾碼函數與首碼函數區別開來。

4、定義尾碼式操作符

class CheckedPtr

{

public:

CheckedPtr &operator++(int);

CheckedPtr &operator--(int);

//AS Before

};

最佳實踐】

為了與內置操作符一致, 尾碼式操作符應返回舊值[即:尚未自增或自減的值], 並且, 應作為值返回, 而不是引用!

CheckedPtr CheckedPtr::operator++(int)

{

CheckedPtr ret(*this);

++ *this;

return ret;

}

CheckedPtr CheckedPtr::operator--(int)

{

CheckedPtr ret(*this);

-- *this;

return ret;

}

必須保存物件在加1/減1之前的當前狀態, 當保存了當前狀態的副本之後, 操作符調用自己的首碼式操作符分別進行加1/減1:

[cpp] view plaincopy

++*this; //-- *this;

調用這個物件自己的已經定義好了的首碼自增/自減操作符, 那些關於curr是否處在beg和end範圍之內的檢查, 以及是否拋出異常, 則由它們代勞了O(∩_∩)O!

由於不使用int形參, 所以對其沒有命名。

5、顯式調用自增/自減操作符

如果想要使用函式呼叫來調用尾碼式操作符,

必須給出一個整型實參值:

[cpp] view plaincopy

CheckedPtr parr(ia,ia+ sizeof(ia)/sizeof(*ia));

parr.operator++(); //顯式調用首碼式

parr.operator++(0); //顯式調用尾碼式

所傳的值通常被忽略, 但是該值是必要的, 用於通知編譯器需要的是尾碼式版本!

【最佳實踐】

一般而言, 最好首碼式和尾碼式都定義, 只定義首碼式或只定義尾碼式的類, 將會讓習慣於使用兩種形式的用戶感到奇怪。

//P449 習題14.23~26 著重複習前面幾節的知識, 由於知識點都比較簡單, 所以幾乎沒有注釋...

#include

#include

usingnamespace std;

class CheckedPtr

{

friendbool operator==(const CheckedPtr &lhs,const CheckedPtr &rhs);

friendbool operator

friendbool operator>(const CheckedPtr &lhs,const CheckedPtr &rhs);

friend CheckedPtr operator+(const CheckedPtr &lhs,constsize_t n);

friend CheckedPtr operator-(const CheckedPtr &lhs,constsize_t n);

friendptrdiff_t operator-(const CheckedPtr &lhs,const CheckedPtr &rhs);

public:

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

CheckedPtr &operator++();

CheckedPtr &operator--();

CheckedPtr operator++(int);

CheckedPtr operator--(int);

int &operator[] (constsize_t);

constint &operator[] (constsize_t) const;

int &operator*();

constint &operator*() const;

private:

int *beg;

int *end;

int *curr;

};

CheckedPtr operator+(const CheckedPtr &rhs,constsize_t n)

{

CheckedPtr ret(rhs);

ret.curr += n;

if (ret .curr > ret.end)

{

throw out_of_range("operator + out_of_range!");

}

return ret;

}

CheckedPtr operator-(const CheckedPtr &rhs,constsize_t n)

{

CheckedPtr ret(rhs);

ret.curr -= n;

if (ret.curr

{

throw out_of_range("operator - out_of_range!");

}

return ret;

}

ptrdiff_t operator-(const CheckedPtr &lhs,const CheckedPtr &rhs)

{

if (!(lhs.beg == rhs.beg && lhs.end == rhs.end))

{

throw out_of_range("operator - out_of_range!");

}

return lhs.curr - rhs.curr;

}

inline

bool operator==(const CheckedPtr &lhs,const CheckedPtr &rhs)

{

return lhs.beg == rhs.beg && lhs.curr == rhs.curr && lhs.end == rhs.end;

}

inline

bool operator!=(const CheckedPtr &lhs,const CheckedPtr &rhs)

{

return !(lhs == rhs);

}

inline

bool operator

{

return lhs.beg == rhs.beg && lhs.end == rhs.end && lhs.curr

}

inline

bool operator>=(const CheckedPtr &lhs,const CheckedPtr &rhs)

{

return !(lhs

}

inline

bool operator>(const CheckedPtr &lhs,const CheckedPtr &rhs)

{

return lhs.beg == rhs.beg && lhs.end == rhs.end && lhs.curr > rhs.curr;

}

inline

bool operator

{

return !(lhs > rhs);

//OR: return lhs == rhs || lhs

}

int &CheckedPtr::operator*()

{

if (curr == end)

{

throw out_of_range("Error Pointer!");

}

return *curr;

}

constint &CheckedPtr::operator*() const

{

if (curr == end)

{

throw out_of_range("Error Pointer!");

}

return *curr;

}

int &CheckedPtr::operator[](constsize_t index)

{

if (beg + index >= end || beg + index

{

throw out_of_range("index: out_of_range!");

}

return *(beg + index);

}

constint &CheckedPtr::operator[](constsize_t index) const

{

if (beg + index >= end || beg + index

{

throw out_of_range("index: out_of_range!");

}

return *(beg + index);

}

CheckedPtr &CheckedPtr::operator++()

{

if (curr == end)

{

throw out_of_range("increment past the end of CheckedPtr");

}

++ curr;

return *this;

}

CheckedPtr &CheckedPtr::operator--()

{

if (curr == beg)

{

throw out_of_range("decrement past the beginning of CheckedPtr");

}

-- curr;

return *this;

}

CheckedPtr CheckedPtr::operator++(int)

{

CheckedPtr ret(*this);

++ *this;

return ret;

}

CheckedPtr CheckedPtr::operator--(int)

{

CheckedPtr ret(*this);

-- *this;

return ret;

}

//測試

int main()

{

int ia[] = {10,8,6,4,2,0};

CheckedPtr flag(ia,ia + sizeof(ia)/sizeof(*ia));

for (CheckedPtr parr(ia,ia + sizeof(ia)/sizeof(*ia));

parr != flag + sizeof(ia)/sizeof(*ia); parr = parr + 2)

{

cout

}

for (CheckedPtr parr(ia,ia + sizeof(ia)/sizeof(*ia));

parr != flag + sizeof(ia)/sizeof(*ia); ++ parr)

{

cout

}

CheckedPtr parr1(ia,ia + sizeof(ia)/sizeof(*ia));

cout

cout

CheckedPtr parr2(ia,ia + sizeof(ia)/sizeof(*ia));

++ parr2;

cout

return 0;

}

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示