如何重载Post-fix操作符? [英] How do I Overload Post-fix operator?

查看:62
本文介绍了如何重载Post-fix操作符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

//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 ints.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆