原例,類
[cpp] //自增自減操作,前綴後綴,後綴調用前綴來實現,同!=調用==
#include"head.h"
//用來處理數組
//後面習題14_23起,對類進行完善,找代碼去後邊
class CheckedPtr{
public:
CheckedPtr(int* b, int* e): beg(b), end(e), curr(b) {}
public:
CheckedPtr& operator++();
CheckedPtr& operator--();
//添加一個沒用的形參,來實現重載,此外,可以利用這個顯式調用後綴操作,注意後綴返回的是原副本
CheckedPtr operator++(int);
CheckedPtr operator--(int);
public:
int getCurr(){return *curr;}
private:
int* beg;
int* end;
int* curr;
};
CheckedPtr& CheckedPtr::operator++(){
if(curr == end)
throw std::out_of_range//<stdexcept>,之前那些都不能用,今次能用了啊,(可能catch之類的還是不行把,那塊跳過了)
("increment past the end of CheckedPtr");
++curr;
return *this;
}
CheckedPtr& CheckedPtr::operator--(){
if(curr == beg)
throw std::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(){
const unsigned size = 10;
int a[size] = {1, 3, 4, 5, 6, 67, 8, 13, 34};
CheckedPtr ptr(a, a + size);
std::cout << ptr.getCurr() << std::endl;
std::cout << (++ptr).getCurr() << std::endl;
std::cout << ptr++.getCurr() << std::endl;
std::cout << ptr.getCurr() << std::endl;
std::cout << (--ptr).getCurr() << std::endl;
std::cout << ptr.operator--(100).getCurr() << std::endl;//顯式調用後綴,參數無任何意義,但是要有
std::cout << ptr.getCurr() << std::endl;
ptr--;
ptr--;//越界錯誤
}
pe14_23.cpp
[cpp]
<pre name="code" class="cpp"><strong><strong><strong><strong>//下標操作符的實現中:
//不同於不可以被當引用返回的臨時變量,臨時建的指針,再解引用,返回就能當引用,具體怎麼理解,不是特別清晰了,解引用了就相當於原對象把<span style="color:#FF0000;">(mark)</span></strong></strong></strong></strong>
發現:csdn的代碼框裡不能給自己設置格式,設置完就亂
[cpp]
#include"head.h"
//為該類重載下標操作符和解引用操作符,使操作符確保CheckedPtr有效:它不應該對超出數組末端的元素進行解引用或索引,並進行測試 www.2cto.com
class CheckedPtr{
//基本同上邊代碼
};
int& CheckedPtr::operator*(){
if(curr > end || curr < beg)
throw std::out_of_range
("out of range~!");
return *curr;
}
int& CheckedPtr::operator[](unsigned index){
if(index >= (end - beg) || index < 0)
throw std::out_of_range
("out of range~!");
int * temp = curr;//需要對原位置進行一個保護
curr = beg;//重置curr,保證每次都是從0計算,得到正確下標
for(unsigned i = 0; i < index; i++)
curr++;
int* ret = curr;
std::cout << "test\t*curr: " << *curr << std::endl;
curr = temp;//還原curr
std::cout << "test\t*curr: " << *curr << std::endl;
return *ret;//既要保護原curr位置,在返回前還原,又要返回引用供修改,,返回*ret就能滿足(下標操作返回引用以供修改)的要求
}
int main(){
//進行自增等操作時注意:ptr是從初始化時傳遞的beg做curr的,之後保存記憶,加到什麼位置算什麼位置
const unsigned size = 10;
int a[size] = {1, 3, 4, 5, 6, 67, 8, 13, 34};
CheckedPtr ptr(a, a + size);
/*下標訪問對curr位置的影響測試。應該避免影響到
std::cout << *ptr << std::endl;
std::cout << ptr[7] << std::endl;
std::cout << std::endl << *ptr << std::endl;
ptr++;
std::cout << *ptr << std::endl;
*/
/*下標訪問與修改測試
for(unsigned i = 0; i < size; i++){
std::cout << ptr[i] << " : ";
ptr[i] = 100;
std::cout << ptr[i] << "\t";
}
*/
//越界測試
//ptr[-1];
//ptr[10];
}
摘自 huqinweI987的專欄