为什么会发生此转换?

时间:2011-09-14 14:08:16

标签: c++ visual-c++ operator-overloading

#include<iostream>

using namespace std;

class test
{
  int a, b;
public:

  test() {
    a=4; b=5;
  }

  test(int i,int j=0) {
    a=i; b=j;
  }

  test operator +(test c) {
     test temp;
     temp.a=a+c.a;
     temp.b=b+c.b;
     return temp;
  }

  void print() {
    cout << a << b;
  }
};

int main() {
  test t1, t2(2,3), t3;
  t3 = t1+2;
  t3.print();
  return 0;
}

编译器如何接受t3=t1+2;之类的语句,其中2不是对象?

7 个答案:

答案 0 :(得分:7)

编译器发现您正在调用operator+(test)并尝试使用您的2构造函数隐式将test转换为test(int i,int j=0)

如果要显式转换,则必须将构造函数更改为explicit test(int i, int j=0)。在这种情况下,您的代码会生成编译器错误,因为2无法隐式转换为test。您需要将表达式更改为t1 + test(2)

答案 1 :(得分:2)

因为test(int i,int j=0)是一个带有一个或两个参数的构造函数,所以从test创建了一个2对象。在下一阶段test operator +(test c)被调用。

答案 2 :(得分:2)

有一个二进制operator+可用,它接受两个类型为test的操作数。此外,test可以通过构造函数inttest(int, int = 0)隐式构造。将两者放在一起,t1 + 2变为t1 + test(2, 0)

要禁止此静默转换(有时可能导致非常令人惊讶的转换链),请声明您的构造函数接受一个明确的参数:explicit test(int, int = 0)

答案 3 :(得分:1)

因为test(int i, int j = 0)未标记为显式。

因此t1 + 2被解释为t1.operator+(2),它本身被解释为t1.operator+(test(2))(隐式转化)。

如果您将构造函数标记为explicit,则会出现错误(在编译期间),说2无法转换为testoperator+不匹配。

答案 4 :(得分:0)

简而言之,因为C ++包含运算符重载,所以能够为用户定义的类型定义运算符的自定义实现。上面显示的operator+()函数是您为类型+定义test运算符的方式。当编译器看到+应用于test对象的表达式时,它会查找operator+中定义的test(或定义为test的双参数形式具有类型test&或{{1}}的第一个参数的全局函数。)然后它可能在转换另一个参数之后调用该函数。

答案 5 :(得分:0)

因为您的构造函数test(int i,int j=0)引入了从inttest的用户定义转换。

答案 6 :(得分:0)

编译器使用其构造函数创建一个Test类型的对象。

 t3 = t1 + test(2);