为什么会发生这种转换
Why is this conversion happening?
#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
不是对象?
看到您正在调用operator+(test)
,并尝试使用 test(int i,int j=0)
构造函数成功将2
隐式转换为test
。
如果要显式转换,则必须将构造函数更改为 explicit test(int i, int j=0)
。在这种情况下,您的代码将生成编译器错误,因为2
无法隐式转换为 test
。您需要将表达式更改为 t1 + test(2)
。
因为test(int i,int j=0)
是一个接受一个或两个参数的构造函数,所以test
对象是从2
创建的。在下一阶段,test operator +(test c)
被调用。
有一个二进制operator+
可用,它需要两个类型 test
的操作数。此外,test
可以通过构造函数test(int, int = 0)
从int
隐式构造。将两者放在一起,t1 + 2
变得t1 + test(2, 0)
.
要禁止这种静默转换(有时会导致非常令人惊讶的转换链(,请将接受单个参数的构造函数声明为显式参数:explicit test(int, int = 0)
。
因为test(int i, int j = 0)
没有明确标记。
因此,t1 + 2
被解释为t1.operator+(2)
而它本身被解释为t1.operator+(test(2))
(隐式转换(。
如果将构造函数标记为 explicit
,则(在编译期间(将发生错误,指出2
无法转换为test
或operator+
不匹配。
简而言之,由于C++包括运算符重载,因此能够为用户定义类型定义运算符的自定义实现。上面显示的operator+()
函数是定义类型 test
的+
运算符的方式。当编译器看到+
应用于test
对象的表达式时,它会查找在test
中定义的operator+
(或定义为全局函数的双参数形式,其第一个参数类型为 test
或 test&
(。然后,它可能在转换另一个参数后调用该函数。
因为构造函数test(int i,int j=0)
引入了从int
到test
的用户定义转换。
编译器使用其构造函数创建 Test 类型的对象。
t3 = t1 + test(2);
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- 为什么mpfr_printf与十六进制浮点(%a转换说明符)的printf不同
- 为什么g++在未执行的代码处标记强制转换错误
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 为什么 openmp 的并行不适用于矢量化色彩空间转换?
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 为什么我的模板化函数需要从一个迭代器转换到另一个迭代器?
- 为什么我收到"从常量指针到指针的转换无效?
- 为什么 c++ 不允许(自动)强制转换?
- 为什么即使我没有进行转换,此代码中也有转换?
- 为什么我会收到此错误?无法将 {lb, ub} 从<大括号括起来的初始值设定项列表>转换为 float(**)(float*, int)
- 为什么下面带有非常量转换函数的代码没有歧义?
- 为什么转换函数声明不需要至少一个定义类型说明符
- 为什么此指针值不能转换为整数的规则是什么?
- 为什么在将 void 指针转换为整数指针时出现分段错误
- 在 OS X 上的 ifconfig.h 的 ifadder 结构中,我可以将ifa_data转换为什么?
- 双精度到浮点型转换 -- 为什么我不能将 (双精度)20150813.00 转换为 (浮点型)20150813.00?
- c++隐式转换:为什么字面字符串要转换为字符串
- Reg 文件 - "dword"转换为什么?