C ++运算符重载和参数化构造函数

时间:2013-06-12 16:45:11

标签: c++ constructor operator-overloading

为什么下面的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;
}

3 个答案:

答案 0 :(得分:3)

首先,ab是默认构造的(按此顺序),这会导致AB打印到标准输出。

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

这是因为operator +的操作数不需要按确定的顺序进行评估。它们仅被授予在operator +被调用之前进行评估(参见C ++ 11标准的第1.9 / 15段)。

所以这个表达式:

(A)b

在给定A类型的对象的情况下,将导致构造B类型的临时对象。这怎么可能?好吧,A有一个接受int的构造函数,而B有一个用户定义的转换为int

因此,用户定义的从bint(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 ++标准只指定:

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

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

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