我听说C++有一种叫做“转换构造函数”或“转换构造器”的东西。这是什么,有什么用?我在看到下面的代码时提到了它:
class MyClass
{
public:
int a, b;
MyClass( int i ) {}
}
int main()
{
MyClass M = 1 ;
}
我听说C++有一种叫做“转换构造函数”或“转换构造器”的东西。这是什么,有什么用?我在看到下面的代码时提到了它:
class MyClass
{
public:
int a, b;
MyClass( int i ) {}
}
int main()
{
MyClass M = 1 ;
}
explicit
构造函数(否则它不会参与隐式转换),但在C++03中它还必须能够接受单个参数。也就是说:struct foo
{
foo(int x); // 1
foo(char* s, int x = 0); // 2
foo(float f, int x); // 3
explicit foo(char x); // 4
};
explicit
的。explicit
声明的构造函数,如果只带一个参数,则指定了从其第一个参数的类型到其类类型的转换。这样的构造函数称为转换构造函数。explicit
声明的构造函数,指定了从其参数类型到其类类型的转换。这样的构造函数称为转换构造函数。foo bar(foo f)
{
return {1.0f, 5};
}
float
和 int
参数的 foo
转换构造函数。此外,我们可以通过 bar({2.5f, 10})
调用此函数。这也是一种转换。因为它们是转换,所以它们使用的构造函数应该是 转换构造函数。foo
的构造函数带有 explicit
函数说明符,则上述代码将无法编译。只有当存在可用于完成工作的转换构造函数时,才能使用上述新语法。
C++11: §6.6.3:
使用带有花括号初始化列表的
return
语句通过从指定的初始化列表进行复制列表初始化(8.5.4)来初始化要从函数返回的对象或引用。
§8.5:
在参数传递中发生的初始化[...]称为复制初始化。
§12.3.1:
显式构造函数像非显式构造函数一样构造对象,但只在直接初始化语法(8.5)或显式使用转换(5.2.9、5.4)时才这样做。
通过转换构造函数隐式转换
让我们将问题中的示例变得更加复杂。
class MyClass
{
public:
int a, b;
MyClass( int i ) {}
MyClass( const char* n, int k = 0 ) {}
MyClass( MyClass& obj ) {}
}
前两个构造函数是转换构造函数。第三个是复制构造函数,因此它也是另一个转换构造函数。
转换构造函数允许从参数类型隐式转换为构造函数类型。这里,第一个构造函数允许将int
转换为MyClass
类的对象。第二个构造函数允许将字符串转换为MyClass
类的对象。而第三个构造函数则将MyClass
类的对象转换为另一个MyClass
类的对象!
要成为转换构造函数,构造函数必须具有单个参数(在第二个构造函数中,第二个参数有一个默认值),并且不能使用关键字explicit
进行声明。
然后,在主函数中初始化可以如下所示:
int main()
{
MyClass M = 1 ;
// which is an alternative to
MyClass M = MyClass(1) ;
MyClass M = "super" ;
// which is an alternative to
MyClass M = MyClass("super", 0) ;
// or
MyClass M = MyClass("super") ;
}
显式关键字和构造函数
那么,如果我们使用了 explicit
关键字呢?
class MyClass
{
public:
int a, b;
explicit MyClass( int i ) {}
}
int main()
{
MyClass M = 1 ;
}
由于这是隐式转换,因此必须编写
int main()
{
MyClass M(1) ;
MyClass M = MyClass(1) ;
MyClass* M = new MyClass(1) ;
MyClass M = (MyClass)1;
MyClass M = static_cast<MyClass>(1);
}
explicit
关键字总是用于防止构造函数的隐式转换,并且它适用于类声明中的构造函数。
X&
、const X&
、volatile X&
或 const volatile X&
。 - Joseph MansfieldMyClass M(1);
等。注意那些多字符字面量。 - chrisexplicit
的构造函数指定了从其参数类型到其类类型的转换。这样的构造函数称为转换构造函数。” - Joseph Mansfield转换构造函数是一种单参数构造函数,它在没有显式函数说明符的情况下声明。编译器使用转换构造函数将对象从第一个参数的类型转换为转换构造函数所属的类的类型。