class Test { int a; public: Test() : a(0) {cout << "void";} explicit Test(int i) : a(i) {cout << "int";} Test(short s) : a(s) {cout << "short";} Test &operator=(int n) {a = n; cout << "operator=";} }; int main() { int n; Test a = n; }
class Test { int a; public: Test() : a(0) {cout << "void";} explicit Test(int i) : a(i) {cout << "int";} Test(short s) : a(s) {cout << "short";} Test &operator=(int n) {a = n; cout << "operator=";} }; int main() { int n; Test a = n; }
int
short
void
void operator=
explicit构造函数的作用
解析:
explicit构造函数是用来防止隐式转换的。请看下面的代码:
class Test1
{
public:
Test1(int n)
{
num=n;
}//普通构造函数
private:
int num;
};
class Test2
{
public:
explicit Test2(int n)
{
num=n;
}//explicit(显式)构造函数
private:
int num;
};
int main()
{
Test1 t1=12;//隐式调用其构造函数,成功
Test2 t2=12;//编译错误,不能隐式调用其构造函数
Test2 t2(12);//显式调用成功
return 0;
}
Test1的构造函数带一个int型的参数,代码23行会隐式转换成调用Test1的这个构造函数。而Test2的构造函数被声明为explicit(显式),这表示不能通过隐式转换来调用这个构造函数,因此代码24行会出现编译错误。
普通构造函数能够被隐式调用。而explicit构造函数只能被显式调用。
所以此处不能调用参数为int的构造函数。我认为此时编译器应该在所有带参构造函数中寻找适合的。因为上述中的n可以被转换为short,所以选择了参数是short的构造函数。 如果把参数short改为string,编译器就会报错,因为n转换不为string。所以选B
explicit是一个关键字,用于修饰类的构造函数。它的作用是防止编译器进行隐式类型转换,只允许显式调用构造函数来创建对象。
当某个构造函数被声明为explicit时,在使用该构造函数进行对象初始化时,必须使用直接的构造函数调用语法,而不能进行隐式类型转换。这样可以避免一些意外的类型转换,增强代码的可读性和安全性。
下面是一个示例说明explicit的作用:
cppCopy Codeclass MyClass { int value; public: explicit MyClass(int val) : value(val) {} int getValue() { return value; } }; int main() { // 隐式类型转换,编译错误 // MyClass obj = 10; // 显式调用构造函数进行对象初始化 MyClass obj(10); int result = obj.getValue(); // result = 10 }
在上述示例中,MyClass类的构造函数被声明为explicit,因此在主函数中不能进行隐式类型转换来创建对象。如果尝试编写MyClass obj = 10;这样的代码,会导致编译错误。相反,我们必须使用显式的构造函数调用MyClass obj(10);来创建对象。
通过使用explicit关键字,可以避免一些潜在的错误和意外的类型转换,提高代码的可靠性和可读性。