前置++与后置++区别

对于前置++与后置++以前只知道它们的两点区别:
1. 前置++:先加再用;后置++:先用后加。
2. ++i效率比i++效率高;

今日又添加一项:
3. 前置++可操作,后置++不可操作

只知其果,不明其因非学者姿态。
下面是前置++与后置++实现的demo:

#include <iostream>
using namespace std;

class Clock {
	int hour, min, second;
public:
	Clock(int newhour, int newmin, int newsecond);
	void showClock()const;
	Clock& operator ++();	//前置++;可操作原因:返回的引用,还可以对对象进行操作。
	Clock operator ++(int);	//后置++;参数为int,用于区别前置++;可使用const修饰
};

Clock::Clock(int newhour, int newmin, int newsecond) {
	if (0<= newhour && newhour < 24 && 0 <= newmin && newmin < 60 &&  0 <=newsecond && newsecond < 60) {
		this->hour = newhour;  //??为什么要加this ,事实证明加不加效果一样。
		this->min = newmin;
		this->second = newsecond;
	}
	else {
		cout << "Time error!" << endl;
	}
}
void Clock::showClock() const {
	cout << hour << ":" << min << ":" << second << endl;
}
Clock& Clock::operator ++() {
	second++;
	if (second >= 60) {
		second -= 60;
		min++;
		if (min >= 60) {
			min -= 60;
			hour = (hour + 1) % 24;
		}
	}
	return *this;
}
Clock Clock::operator ++(int) { //返回一定为对象嘛?看情况,大部分是。
	Clock old = *this;	//后置++效率低一点的原因。
	++(*this);
	return old;	//返回的是右值,是副本
}


int main()
{
	Clock myclock(22, 59, 59);
	cout << "第一次时间: ";
	myclock.showClock();
	cout << "Clock++: ";
	(myclock++).showClock();
	cout << "++Clock: ";
	(++myclock).showClock();
	return 0;
}

//result:
//第一次时间: 22:59 : 59
//Clock++ : 22 : 59 : 59
//++Clock : 23 : 0 : 1

拓:
左值:指表达式结束后依然存在的持久对象,可以取地址,具名变量或对象
右值:表达式结束后就不再存在的临时对象,不可以取地址,没有名字。

在编程语言中,尤其是如C++这样的语言,前置递增(`++i`)后置递增(`i++`)运算符的主要区别体现在返回值、语义行为以及在复杂类型上的实现方式上。 对于基本数据类型而言,前置递增操作会先将变量的值增加1,然后返回增加后的值。例如,在表达式`int a = ++b;`中,变量`b`的值首先被加1,之后这个新值被赋给变量`a`。而后置递增则是在执行完当前表达式之后才进行自增操作,因此它返回的是变量自增前的原始值。这意味着如果使用相同的表达式`int a = b++;`,那么`a`将会得到`b`原来的值,而`b`自身会在该表达式执行完毕后增加1[^1]。 当涉及到用户定义类型的对象时,比如类实例,这种差异变得更加明显且重要。为了支持这些操作,通常需要为类重载相应的运算符。对于前置递增,通常只需要一个参数-less的成员函数或友元函数来实现;而对于后置递增,则必须提供一个额外的int参数以区分是前置还是后置形式。这是因为编译器通过是否有这个未使用的int参数来识别调用哪一个版本的运算符函数。前置版本可以直接修改对象的状态并返回引用,但后置版本往往需要创建临时对象来保存旧值,并在操作完成后返回此临时值,这可能导致效率上的损失[^2]。 此外,在实际应用中选择合适的递增方式也会影响代码性能逻辑清晰度。由于后置递增可能涉及创建临时对象,所以在可以使用前置递增的情况下优先考虑前置形式,除非特定情况下确实需要利用到后置递增的行为特性[^3]。 ```cpp // 示例:MyInteger 类中的前置后置递增运算符重载 class MyInteger { private: int value; public: // 构造函数 MyInteger(int val) : value(val) {} // 前置递增运算符重载 MyInteger& operator++() { ++value; return *this; } // 后置递增运算符重载 MyInteger operator++(int) { MyInteger temp(*this); // 创建当前状态的副本 ++(*this); // 调用前置递增 return temp; // 返回旧值 } // 用于输出MyInteger对象的值 friend std::ostream& operator<<(std::ostream& os, const MyInteger& mi); }; // 重载<<运算符以便于打印MyInteger对象 std::ostream& operator<<(std::ostream& os, const MyInteger& mi) { os << mi.value; return os; } ``` 上述代码展示了如何在一个简单的`MyInteger`类中实现前置后置递增运算符。注意,前置版本返回的是调用对象本身的引用,而后者返回的是自增前的对象拷贝。 综上所述,理解前置递增后置递增之间的区别不仅有助于正确地编写程序逻辑,而且对于优化程序性能也有着重要的意义。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值