为什么会发生这种转换?

4
#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 不是对象?

我理解你的困惑,但从技术上讲,int 也是对象。 - R. Martinho Fernandes
7个回答

7
编译器发现您正在调用operator+(test)并尝试使用您的test(int i,int j=0)构造函数将2隐式转换为test
如果您想使转换显式,必须将构造函数更改为explicit test(int i, int j=0)。在这种情况下,您的代码将生成编译器错误,因为2无法隐式转换为test。您需要将表达式更改为t1 + test(2)

2

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


2

现有一个二进制运算符operator+,它接受两个类型为test的操作数。此外,可以通过构造函数test(int, int = 0)test隐式转换为int。结合在一起,t1 + 2变成了t1 + test(2, 0)

如果不想允许这种悄无声息的转换(有时可能会导致非常令人惊讶的转换链),请将接受一个单一参数的构造函数声明为显式:explicit test(int, int = 0)


1
因为test(int i, int j = 0)没有标记为显式。
因此,t1 + 2被解释为t1.operator+(2),这本身被解释为t1.operator+(test(2))(隐式转换)。
如果将构造函数标记为explicit,则会出现错误(在编译期间),指出2无法转换为testoperator+不匹配。

0
编译器使用构造函数创建一个类型为Test的对象。
 t3 = t1 + test(2);

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

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接