原例,类
//自增自减操作,前缀后缀,后缀调用前缀来实现,同!=调用==
#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
//下标操作符的实现中: //不同于不可以被当引用返回的临时变量,临时建的指针,再解引用,返回就能当引用,具体怎么理解,不是特别清晰了,解引用了就相当于原对象把(mark)
发现:csdn的代码框里不能给自己设置格式,设置完就乱
#include"head.h" //为该类重载下标操作符和解引用操作符,使操作符确保CheckedPtr有效:它不应该对超出数组末端的元素进行解引用或索引,并进行测试 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]; }
pe14_25,模仿数组指针,定义相关操作(不过必须限制b和e相同,至少也是b相同吧)
bool CheckedPtr::operator<(const CheckedPtr& rhs){ if((curr - beg) < (rhs.curr - rhs.beg)) return 1; return 0; } bool CheckedPtr::operator==(const CheckedPtr& rhs){ if((curr - beg) == (rhs.curr - rhs.beg)) return 1; return 0; }
int main(){
const unsigned size = 10;
int a[size] = {1, 3, 4, 5, 6, 67, 8, 13, 34};
CheckedPtr ptr1(a, a + size);
CheckedPtr ptr2(a, a + size);
//测试<和==符号的使用,前提是都指向同一范围
std::cout << "(ptr1 == ptr2)? " << (ptr1 == ptr2) << std::endl;
std::cout << "(ptr1 < ptr2)? " << (ptr1 < ptr2) << std::endl;
ptr2++;
std::cout << "After ptr2 increment:" << std::endl;
std::cout << "(ptr1 == ptr2)? " << (ptr1 == ptr2) << std::endl;
std::cout << "(ptr1 < ptr2)? " << (ptr1 < ptr2) << std::endl;
}
pe14_26.cpp
//指针相加没什么意义,指针相减就是给个差,基本上说加减法是加减数字来完成指向位置的变化
//版本二,优化,遇到负数参数直接调用另一种操作符,另外可加const对传入的参数加以保护
CheckedPtr CheckedPtr::operator+(int change){//不限制正负号会比较麻烦,只为满足 ptr + (-10);这种操作 if((curr + change) < beg || (curr + change) >= end)//还要判断出界问题 throw std::out_of_range ("out of range"); CheckedPtr ret(beg, end); ret.curr = curr;//必要:不然加法不具备累积性,ptr + 1; ptr + 2;总共算+2 if(change >= 0) for(int i = 0; i < change; i++) ret++; else for(int i = 0; i > change; i--) ret--; return ret; } CheckedPtr CheckedPtr::operator-(int change){//不限制正负号会比较麻烦,只为满足 ptr - (-10);这种操作 if((curr - change) < beg || (curr - change) >= end)//还要判断出界问题 throw std::out_of_range ("out of range"); CheckedPtr ret(beg, end); ret.curr = curr;//必要:不然加法不具备累积性,ptr + 1; ptr + 2;总共算+2 if(change >= 0) for(int i = 0; i < change; i++) ret--; else for(int i = 0; i > change; i--) ret++; return ret; } int main(){ const unsigned size = 10; int a[size] = {1, 3, 4, 5, 6, 67, 8, 13, 34}; CheckedPtr ptr1(a, a + size); CheckedPtr ptr2(a, a + size); //测试加法 std::cout << *ptr2 << std::endl; ptr2 = ptr2 + 3; std::cout << *ptr2 << std::endl; ptr2 = ptr2 + 4; std::cout << *ptr2 << std::endl; ptr2 = ptr2 + (-1);//加负数,另一种思路是用判断条件,如果有加负数,直接调用减法操作符,有待添加 std::cout << *ptr2 << std::endl; ptr2 = ptr2 - 1; std::cout << "after ptr2 - 1 : " << *ptr2 << std::endl; ptr2 = ptr2 - (-3);//减负数,另一种思路是用判断条件,如果有减负数,直接调用加法操作符,实现有待添加 std::cout << "after ptr2 - (-3) : " << *ptr2 << std::endl; //ptr2 - (-2);//越上界 //ptr2 = ptr1 + 11;//测试越界 //ptr }