为什么下面的C ++程序输出“ABaBbAc”?
#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;
}
答案 0 :(得分:3)
首先,a
和b
是默认构造的(按此顺序),这会导致AB
打印到标准输出。
在此之后,程序的输出可能与您正在观察的程序不同(或者可能正是您正在观察的那个 - 阅读)。
这是因为operator +
的操作数不需要按确定的顺序进行评估。它们仅被授予在operator +
被调用之前进行评估(参见C ++ 11标准的第1.9 / 15段)。
所以这个表达式:
(A)b
在给定A
类型的对象的情况下,将导致构造B
类型的临时对象。这怎么可能?好吧,A
有一个接受int
的构造函数,而B
有一个用户定义的转换为int
。
因此,用户定义的从b
到int
(1)的转化负责打印b
。然后,生成的A
(2)中int
临时文件的构造负责打印A
。
对称,表达式:
(B)a
将导致构造B
类型的临时对象,该临时对象是由用户定义的a
转换为int
的结果构建的。此转换(3)负责打印a
,而B
temporary(4)的构造负责打印B
。
最终,评估表达式(A)b
和(B)a
产生的两个临时值被用作operator +
(5)的参数,后者负责打印{{1} }}
现在C ++标准只指定:
除此之外,未指定评估的顺序。这意味着输出必须是:
C
如果问题标记应由满足上述约束条件的(1),(2),(3)和(4)的输出的可允许排列代替。
答案 1 :(得分:0)
好吧,看看代码!
类A
的构造函数输出字符A
。
类B
的构造函数输出字符B
。
所以现在我们在“AB”
operator int()
被称为转换运算符,它允许使用类来代替整数。因此,当您将(A)
换行时,您正在调出输出operator int()
的{{1}}。与a
当你调用(B)
或反过来时,你正在创建一个(B)a
类型的临时对象,再次调用构造函数。与A
转化相同。
这就是(A)b
的来源。
最后一件事是aBbA
,它会输出operator +
,但我认为您的代码不正确,因为它似乎是大写的。
所以最终输出为c
。
答案 2 :(得分:0)
前两个字符是没脑子的..
我通过调试器运行代码并注意到+运算符的操作数按右操作数的顺序进行计算,然后是左操作数
因此对于(A)b +(B)a
(B)首先从左到右评估a的B的构造函数,然后是'cast to int。
左操作数类似
(A)的构造函数然后是b的int cast。
然后+运算符被称为打印c