[英]How does constructor conversion work in C++?
构造函数转换如何工作?
#include <iostream>
using namespace::std;
class One {
public:
One() { cout<<"One"<<endl;}
};
class Two {
public:
Two(const One&) {cout<<"Two(const One&)"<<endl;}
};
void f(Two) {cout<<"f(Two)"<<endl;}
int main() {
One one;
f(one);
}
产生输出
One
Two(const One&)
f(Two)
可以使用单个参数调用的任何构造函数都被视为implicit conversion constructor
。 这包括简单的一参数情况和默认参数的用法。
在需要X并提供Y的任何上下文中都可以考虑此转换,并且Y具有这种隐式转换的可能性。 请注意,其他许多内置转换也可以混合使用(例如调整const-ness,积分和fp促销,转换等)。规则是,在代码中最多允许一个“用户定义”隐式转换混合。
在某些情况下,这可能非常令人惊讶,因此一般的建议是使任何此类ctor explicit
。 该关键字使转换成为可能,但不是隐含的:您必须使用T()语法强制进行转换。
例如,考虑一个std::vector
,它的ctor取size_t,设置初始大小。 这是明确的-否则您的foo(vector<double> const& )
函数可能会被foo(42)错误地调用。
是正确的结果。 由于constructor
不是explicit
-隐式转换有效(此处One
被隐式转换为Two
)。
创建one
,然后在传递给f
转换为Two
。
编译器必须在堆栈上创建Two
实例的副本。 当您使用作为类One
(或任何其他对象f()
对象的参数调用f()
,编译器将查看类Two
定义,并尝试查找以One
(或任何其他)对象(或引用)作为参数的构造函数。 找到这样的构造函数后,它将使用它构造对象。 之所以称其为隐式,是因为编译器在没有干扰的情况下执行了此操作。
class Foo {
public:
Foo(int number) {cout<<"Foo(int number)"<<endl;}
};
void f(Foo) {cout<<"f(Foo)"<<endl;}
int main() {
f(24);
} ///:~
输出将是:Foo(int number)f(Foo)
Two(const One&) {cout<<"Two(const One&)"<<endl;}
构造函数的意思是,您可以随时从One
隐式构造一个Two
值。 当您调用f(one)
它需要一个Two
参数,它被赋予一个One
,因此编译器将2和2放在一起,并说:“我将从One
创建一个临时的Two
并完成对f()
的调用”。每个人都会很高兴。 欢呼!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.