如何重载Post-fix操作符? [英] How do I Overload Post-fix operator?
问题描述
//Usgage 01:
int x = 15;
int y = 10;
int m = 5;
int n = 5;
int r = x++ + y++ + x++ + y++;
int r2 = x + y;
r的结果是50.
问题是,
如何在只有一个数字并获得与r中所示相同结果的类上实现Post-fix运算符?我希望这是不可能的...有人可以证明我错了吗?
The result in r is 50.
Question is,
How Do I implement the Post-fix operator on a class having only one number and getting the same result as shown in r? I hope that is not possible... Can somebody prove that I am wrong?
推荐答案
这是一个有趣的问题。我认为答案是它取决于编译器。
C ++标准没有严格定义后缀运算符的评估顺序。
所以,如果你有以下程序,例如;
It's an interesting problem you have there. I think the answer is that it depends on the compiler.
The C++ Standard does not strictly define the evaluation order for postfix operators.
So, if you have the following program for example;
#include<iostream>
class number {
private:
int value;
public:
number(const number& other) {
value = other.value;
}
number(const int initial_value) {
value = initial_value;
}
const int get_value() const {
return value;
}
number operator++(const int) {
number old(*this);
++value;
return old;
}
};
number operator+(const number& lhs, const number& rhs) {
return number(lhs.get_value() + rhs.get_value());
}
void main() {
number x = 15;
number y = 10;
number r = x++ + y++ + x++ + y++;
std::cout << "r =" << r.get_value() << std::endl;
int ix = 15;
int iy = 10;
int ir = ix++ + iy++ + ix++ + iy++;
std::cout << "ir=" << ir << std::endl;
}
它为自定义类产生 52 的值和 50
int
s。
这个原因可以在反汇编中看到:
It produces a value of 52 for the custom class number
and 50 for the int
s.
The reason for this can be seen in the disassembly:
35: number x = 15;
009C1386 6A 0F push 0Fh
009C1388 8D 4D F4 lea ecx,[x]
009C138B E8 A7 FC FF FF call number::number (9C1037h)
36: number y = 10;
009C1390 6A 0A push 0Ah
009C1392 8D 4D F8 lea ecx,[y]
009C1395 E8 9D FC FF FF call number::number (9C1037h)
37: number r = x++ + y++ + x++ + y++;
009C139A 6A 00 push 0
009C139C 8D 45 E4 lea eax,[ebp-1Ch]
009C139F 50 push eax
009C13A0 8D 4D F8 lea ecx,[y]
009C13A3 E8 A8 FC FF FF call number::operator++ (9C1050h)
009C13A8 50 push eax
009C13A9 6A 00 push 0
009C13AB 8D 4D E0 lea ecx,[ebp-20h]
009C13AE 51 push ecx
009C13AF 8D 4D F4 lea ecx,[x]
009C13B2 E8 99 FC FF FF call number::operator++ (9C1050h)
009C13B7 50 push eax
009C13B8 6A 00 push 0
009C13BA 8D 55 DC lea edx,[ebp-24h]
009C13BD 52 push edx
009C13BE 8D 4D F8 lea ecx,[y]
009C13C1 E8 8A FC FF FF call number::operator++ (9C1050h)
009C13C6 50 push eax
009C13C7 6A 00 push 0
009C13C9 8D 45 D8 lea eax,[ebp-28h]
009C13CC 50 push eax
009C13CD 8D 4D F4 lea ecx,[x]
009C13D0 E8 7B FC FF FF call number::operator++ (9C1050h)
009C13D5 50 push eax
009C13D6 8D 4D D4 lea ecx,[ebp-2Ch]
009C13D9 51 push ecx
009C13DA E8 53 FC FF FF call operator+ (9C1032h)
009C13DF 83 C4 0C add esp,0Ch
009C13E2 50 push eax
009C13E3 8D 55 D0 lea edx,[ebp-30h]
009C13E6 52 push edx
009C13E7 E8 46 FC FF FF call operator+ (9C1032h)
009C13EC 83 C4 0C add esp,0Ch
009C13EF 50 push eax
009C13F0 8D 45 E8 lea eax,[r]
009C13F3 50 push eax
009C13F4 E8 39 FC FF FF call operator+ (9C1032h)
009C13F9 83 C4 0C add esp,0Ch
38: std::cout << "r =" << r.get_value() << std::endl;
009C13FC 8B 0D 9C 82 9C 00 mov ecx,dword ptr [__imp_std::endl (9C829Ch)]
009C1402 51 push ecx
009C1403 8D 4D E8 lea ecx,[r]
009C1406 E8 3B FC FF FF call number::get_value (9C1046h)
009C140B 50 push eax
009C140C 68 30 58 9C 00 push offset std::_Iosb<int>::end+4 (9C5830h)
009C1411 8B 15 A4 82 9C 00 mov edx,dword ptr [__imp_std::cout (9C82A4h)]
009C1417 52 push edx
009C1418 E8 06 FC FF FF call std::operator<<<std::char_traits<char> > (9C1023h)
009C141D 83 C4 08 add esp,8
009C1420 8B C8 mov ecx,eax
009C1422 FF 15 A8 82 9C 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (9C82A8h)]
009C1428 8B C8 mov ecx,eax
009C142A FF 15 A0 82 9C 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (9C82A0h)]
39:
40: int ix = 15;
009C1430 C7 45 F0 0F 00 00 00 mov dword ptr [ix],0Fh
41: int iy = 10;
009C1437 C7 45 EC 0A 00 00 00 mov dword ptr [iy],0Ah
42: int ir = ix++ + iy++ + ix++ + iy++;
009C143E 8B 45 F0 mov eax,dword ptr [ix]
009C1441 03 45 EC add eax,dword ptr [iy]
009C1444 03 45 F0 add eax,dword ptr [ix]
009C1447 03 45 EC add eax,dword ptr [iy]
009C144A 89 45 FC mov dword ptr [ir],eax
009C144D 8B 4D EC mov ecx,dword ptr [iy]
009C1450 83 C1 01 add ecx,1
009C1453 89 4D EC mov dword ptr [iy],ecx
009C1456 8B 55 F0 mov edx,dword ptr [ix]
009C1459 83 C2 01 add edx,1
009C145C 89 55 F0 mov dword ptr [ix],edx
009C145F 8B 45 EC mov eax,dword ptr [iy]
009C1462 83 C0 01 add eax,1
009C1465 89 45 EC mov dword ptr [iy],eax
009C1468 8B 4D F0 mov ecx,dword ptr [ix]
009C146B 83 C1 01 add ecx,1
009C146E 89 4D F0 mov dword ptr [ix],ecx
43:
44: std::cout << "ir=" << ir << std::endl;
您可以看到,对于 int
场景,首先执行添加(而不是后缀),然后执行该总和计算四个加1执行,解释 50 的值。
如果数字
class,编译器决定先运行后缀运算符,改为将结果更改为 52 。
编译器保留做这样的事情的权利,以便能够进行优化。
希望这会有所帮助,
Fredrik
You can see that for the int
scenario the adds (not the postfixs) are executed first, then when that sum is calculated four add 1 are executed, explaining the value of 50.
In the case of the number
class, the compiler has decided to run the postfix operators first, changing the result to 52 instead.
The compiler reserves the right to do things like this in order to be able to optimize.
Hope this helps,
Fredrik
解决方案2非常正确。如果你想获得与整数postfix相同的行为,你必须实现一个助手类,它在构造中存活并在析构函数上执行增量。
也许这段代码片段可以帮助您:
The Solution 2 is quite right. If you want to get the same behaviour as integer postfix you have to implement a helper class that survives the construct and performs the increment on destructor.
perhaps this code snippet can help you:
template <typename TI>
class tI
{
private:
class tIp : public tI
{
public:
tIp(tI& tir,const TI ti,const TI inc):tI(ti),_tir(tir),_inc(inc){}
~tIp(){ _tir += _inc; }
private:
tI& _tir;
const TI _inc;
};
public:
tI(const TI ti) { _ti = ti; }
operator const TI () { return _ti; }
tI& operator = (const tI ti) { _ti = ti._ti; return *this; }
tI& operator += (const TI ti) { _ti += ti; return *this; }
tI operator + (const tI ti) { return ti._ti + _ti; }
tIp operator ++ (const int) { TI ti = _ti; return tIp(*this,ti,+1); }
tIp operator -- (const int) { TI ti = _ti; return tIp(*this,ti,-1); }
private:
TI _ti;
};
void Usgage01()
{
//Usgage 01:
int x = 15;
int y = 10;
int m = 5;
int n = 5;
int r = x++ + y++ + x++ + y++;
int r2 = x + y;
_tprintf(__TEXT("r = %i, r2 = %i\r\n"),r,r2);
}
template <typename TI>
void UsgageT()
{
tI<TI> x = 15;
tI<TI> y = 10;
tI<TI> m = 5;
tI<TI> n = 5;
tI<TI> r = x++ + y++ + x++ + y++;
tI<TI> r2 = x + y;
_tprintf(__TEXT("r = %i, r2 = %i\r\n"),(int)(TI)r,(int)(TI)r2);
}
int _tmain(int argc, _TCHAR* argv[])
{
Usgage01();
UsgageT<int>();
UsgageT<unsigned int>();
UsgageT<char>();
UsgageT<unsigned char>();
UsgageT<short>();
UsgageT<unsigned short>();
UsgageT<long>();
UsgageT<unsigned long>();
UsgageT<__int64>();
UsgageT<unsigned __int64>();
_tprintf(__TEXT("<key> ")); _gettch();
return 0;
}
祝你好运。
Best regards.
你想听到,你可以这些运营商超负荷?嗯,坏消息:你可以。
看看这里: http://www.learncpp.com/cpp-tutorial/97-overloading-the-increment-and-decrement-operators/ [ ^ ]
You want to hear, that you can't overload such operators? Well, bad news: you can.
Take a look here: http://www.learncpp.com/cpp-tutorial/97-overloading-the-increment-and-decrement-operators/[^]
这篇关于如何重载Post-fix操作符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!