2013-06-12 77 views
2

为什么下面的C++程序输出“ABaBbAc”?C++运算符重载和参数化构造函数

#include "stdafx.h" 
#include <iostream> 

using namespace std; 

class A { 
public: 
    int i; 
    A(int j=0):i(j) 
    { 
     cout<<"A"; 
    } 
    operator int() 
    { 
     cout<<"a"; 
     return 2; 
    } 
}; 

class B { 
public: 
    B(int j=1):i(j){ 
     cout<<"B"; 
    } 
    operator int() { 
     cout<<"b"; 
     return 3; 
    } 
    int i; 
}; 

int operator+(const A&a, const B&b){ 
    cout<<"C"; 
    return a.i + b.i; 
} 

int main() 
{ 
    A a; 
    B b; 

    int i = (A)b + (B)a; 
    return 0; 
} 
+1

你会期望它做什么? – Beta

+0

这是一个编程面试问题,我无法理解.. – RDX

+1

字符串中的小写字母a和b表示A和B类型的相应对象resp被转换为某个int值 – damienh

回答

3

首先,ab是默认构造(以该顺序),并且这导致AB要打印到标准输出。

在此之后,程序的输出可能与您正在观察的程序(或可能正是您正在观察的那个程序 - 请继续阅读)中的不同。

这是因为operator +的操作数不需要按照确定的顺序进行评估。只有在调用operator +之前,才允许它们进行评估(参见C++ 11标准的第1.9/15段)。

所以这个表达式:

(A)b 

将导致给定的结构类型B的目的A类型的临时对象的。这怎么可能?那么,A有一个构造函数接受intB有一个用户定义的转换为int

因此,从bint(1)的用户定义转换负责打印b。然后,由int(2)产生的A临时建筑负责打印A

对称地,表达式:

(B)a 

会导致B类型的临时对象,从a用户定义转化为int的结果构造的构造。此转换(3)负责打印a,而B的建设临时(4)负责打印B

最终,从表达式(A)b(B)a的评价得到的两种临时对象被用作参数的operator +(5),它负责打印C

现在C++标准仅规定:

  • (1) - (4)之前必须评价(5)
  • (1)必须在(2)
  • (3被评估)必须在评估之前(4)

除此之外,评估的排序是未指定的。这意味着,输出必须是这样的:

AB????C 

其中问号应的输出的可容许的排列替换(1),(2),(3)和(4)满足上面指定的约束。

0

那么,看代码!

A的构造函数输出字符A

B的构造函数输出字符B

所以现在我们在“AB”

operator int()被称为转换操作符,它允许在地方的整数要使用的类。所以当你打包(A)时,你打电话operator int(),其输出a。与(B)

相同当您调用(B)a或者相反时,您正在创建类型为A的临时对象,再次调用构造函数。与(A)b转换相同。

这就是aBbA的来源。

最后一点是operator +,它输出c,但我认为你的代码是不正确的,因为它似乎是大写。

所以最终的输出是ABaBbac

0

第2个字符是没有brainers ..

我通过调试运行的代码,并注意到+运营商的操作数在右操作数的顺序进行评估,然后先左操作

所以对于(A)b +(B)a

(B)首先从左到右评估a执行它的B的构造函数,然后'cast到int。

类似地,对于左操作数

(A)的构造则b的INT铸造。

然后+操作员被称为打印c