当前位置:编程学习 > C/C++ >>

自增自减操作符的前后缀,下标和解引用操作与自增自减一起使用

原例,类


[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++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,