2012-02-29 147 views
2

我有一个用例 如果我有5类A,B,C,d,E和它们作为A,B,C,d的实例,电子+运算符重载在C++

如果有一个表达 a = b + c + d + e;

调用operator +和operator =的顺序是什么? 什么是创建的临时对象。

能否请你帮我

+1

如果您重载这些操作符,则可以使用调试器或诊断输出来确定顺序。当你这样做会发生什么? – 2012-02-29 08:50:55

回答

2

+是左关联的。 =是正确的联想。该命令将

  • d + e使临时de
  • de + c提供临时cde。这是通过呼叫类C的运营商+采取任何类的参数临时de是一个实例。
  • cde + b使临时bcde。这是通过调用类B的运营商+来获得cde类的参数。
  • bcde的值分配给变量a

这里的临时情况是一般情况,这取决于您实际上对您的过载会发生什么。临时的左边的类将被称为使用临时的参数,而不是相反。

使用+时,评估从左到右进行,但实际计算是另一种方式。

+0

因此,类D的operator +将首先被调用,就像operator +(E&e)一样。那么基于它返回的是什么D/E对象,那个对象operator +将被称为或者C类的operator +被调用? – mSO 2012-02-29 08:55:36

+0

是的,它会从右到左,而且你不能确定临时对象,因为别人说它取决于你的实现和你正在使用的编译器。试用一下调试器,它可能是最好的方式来看到它的行动! – Dervall 2012-02-29 08:57:19

+0

Class'C's operator +将被调用临时返回类型。 – Dervall 2012-02-29 08:58:40

2
a = b + c + d + e; 

上的=的r.h.s表达将首先评估,然后=将被调用到结果分配给变量上l.h.s.

r.h.s上的表达式将从右到左进行评估。

检查operator precedence

另外,还要注意代临时在这种情况下,就会被取决于:

  • 重载+操作&
  • 编译器的实现使用
+0

只是一个说明,但运算符优先级不**控制调用运算符重载函数的顺序。 (除了间接的,在这里,因为优先级会创建操作数依赖关系。) – 2012-02-29 09:29:43

0

完全参考here

添加从右到左执行。该作业是最后执行的。根据优化,可能没有任何临时产生:

int x,y,z,k; 
    x = y = z = k = 3; 
    int l = x + y + z + k; 
    cout << l; 
00401000 mov   ecx,dword ptr [__imp_std::cout (402038h)] 
00401006 push  0Ch 
00401008 call  dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40203Ch)] 
+0

我很好奇如何不能有一个临时的。任何合理的'operator +'实现都会返回一个临时的,并且没有可以被删除的非临时的副本。所以我认为至少应该有三个临时对象。 – 2012-02-29 09:28:35

+0

@JamesKanze我用我能想到的最明显的例子更新了我的答案。 – 2012-02-29 09:31:17

+0

你不能用int来判断是否有临时的。我们在这里讨论用户定义的'operator +',返回一个类的类型。 (否则,关于临时工的问题没有意义。) – 2012-02-29 11:55:00

0

希望它不是一个功课

http://en.cppreference.com/w/cpp/language/operator_precedence

+ precedence is higher than = 

这样+第一,它读取从左到右

然后=,它从右读取到左

对于临时对象,抱歉,我不知道它。

+0

不!我有一个项目,我正在添加自定义数学对象。 Int,Complex Number,vector .... – mSO 2012-02-29 09:01:04

+0

我明白了。对于温度。对象,显然如果它是原始gcc没有优化,b + c转向临时对象bc,然后继续+ d等等。为了计算,如果你的类中的所有变量都是原始类型,你不需要重载任何+或=运算符,C++会照顾你。否则你需要自己处理你的“加号”逻辑:) – Tommy 2012-02-29 09:13:58

1

没有序列点,所以唯一的限制是运算符的参数必须在运算符本身调用 之前进行评估。你的情况:

a = b + c + d + e; 

表示:

a = (((b + c) + d) + e); 

成为:

a.operator=(operator+(operator+(operator+(b, c), d), e)); 

(我假设这里operator=是一个成员,是由 标准要求,但是operator+是通常的免费功能。)

碰巧,在这个特定的表达式中,操作数依赖关系 强加严格的顺序。

对于临时工,这取决于operator+实施, 而是给它的常用语义的运营商,这是必要的每个 调用返回一个临时的(而不是引用)。在这种情况下,您将有 有3个临时对象,一旦在每个对象operator+, 的返回处创建,并且在完整表达式的末尾都会被破坏。

+0

你确定这是对的,我认为它会好像你写了a = b +(c +(d + e));作为+是从左到右联想?我可能是错的... – jcoder 2012-02-29 10:58:37

+0

@JohnB生产是_additive-expression_:_additive-expression_ + _multiplicative-expression_。所以在'a + b + c'中,'a + b'首先被减少。这也是我通过左联合来理解的:左边的操作符被首先分组。 (这也对应于维基百科的解释。) – 2012-02-29 11:52:40

+0

这也是一个ANSEER – mSO 2012-02-29 12:44:00

0

执行的顺序没有因过载而改变。正常的C++运算符优先级和操作数评估规则适用。