自增自减操作符的前后缀,下标和解引用操作与自增自减一起使用
原例,类
[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.zzzyk.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的专栏
补充:软件开发 , C++ ,