有一些代码如下:
class A{
private :
int a, b;
public :
A(int x):a(x),b(a*a){}
int getA(){
return a;
}
int getB(){
return b;
}
};
int main(){
A a=13;
printf("%d %dn", a.getA(), a.getB() );
return 0;
}
行A a=13
,我不明白它是如何调用构造函数的,为什么?我认为没有任何关于强制转换的定义,也不会被编译,但它运行良好,并调用了构造函数。
这被称为隐式声明。当您编写A a=13;
时,您的编译器足够聪明,可以识别出您真正的意思是A a(13);
,因为您已经声明了一个以int为参数的构造函数。如果您不希望发生这种情况,请在构造函数前面放一个explicit
关键字,然后除非您写A a(13);
而不是A a=13;
,否则您将得到编译器错误。
采用单个参数的非显式构造函数可以用作转换构造函数,以将参数类型隐式转换为类类型。
因此该构造函数用于将13
转换为类型A
。
如果需要,可以通过使构造函数显式来防止隐式转换:
explicit A(int x):a(x),b(a*a){}
这仍然可以用于显式转换:
A a1(13); // OK: explicit conversion
A a2 = A(13); // OK: explicit conversion
A a3 = 13; // Error: implicit conversion not allowed via explicit constructor
您似乎不知道转换构造函数。转换构造函数是一个只接受一个参数并构造该类对象的构造函数。它的工作原理类似于从某种类型到类的转换,因此命名为转换构造函数。
当编译器看到两种不同的类型并试图通过寻找可能的转换来使它们兼容时,就会发生隐式转换,我认为这就是这里让您感到困惑的地方。
正如您所看到的,隐式转换会导致很多混乱(int也可以是a?!)。因此,您应该小心类中的转换构造函数,并在必要时使用explicit
关键字。
explicit A(int i);
当您将转换构造函数指定为explicit
时,这将"告诉"编译器不要对此类型执行任何隐式转换。当这种情况发生时,您只能通过使用诸如static_cast<int>(a);
之类的强制转换来进行转换。
感谢您的阅读。