【问题标题】:C++ operator overloading and parameterized constructorsC++ 运算符重载和参数化构造函数
【发布时间】:2013-06-12 16:45:10
【问题描述】:

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

【问题讨论】:

  • 你希望它做什么?
  • 这是一道编程面试题,我看不懂..
  • 字符串中的小写字母a和b分别表示A和B类型的对应对象分别转换为某个int值

标签: c++ constructor operator-overloading


【解决方案1】:

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

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

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

所以这个表达式:

(A)b

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

所以用户定义的从b到int的转换(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) 的输出的可接受排列,以满足上述规定的约束。

【讨论】:

    【解决方案2】:

    好吧,看代码!

    类A的构造函数输出字符A。

    类B的构造函数输出字符B。

    所以现在我们在“AB”

    operator int() 称为转换运算符,它允许使用类代替整数。因此,当您包装(A) 时,您调用的是输出a 的operator int()。与(B) 相同

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

    这就是aBbA 的来源。

    最后是operator +,它输出c,尽管我认为您的代码不正确,因为它似乎是大写的。

    所以最终的输出是ABaBbac。

    【讨论】:

      【解决方案3】:

      前 2 个字符不费吹灰之力..

      我通过调试器运行代码,发现 + 运算符的操作数是按照右操作数先到左操作数的顺序计算的

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

      (B) a 首先从左到右求值,执行其 B 的构造函数,然后将 a' 强制转换为 int。

      左操作数也是如此

      (A) 的构造函数,然后是 b 的 int cast。

      那么+操作符就叫做打印c

      【讨论】:

        猜你喜欢
        • 2016-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-28
        • 2011-06-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多