自增自减操作符的前后缀,下标和解引用操作与自增自减一起使用,还有指针加减法的实现--围绕CheckedPtr类

原例,类


//自增自减操作,前缀后缀,后缀调用前缀来实现,同!=调用==
#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
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值