构造函数转换如何在C ++中工作?

时间:2013-06-20 09:14:41

标签: c++ constructor implicit-conversion

构造函数转换如何工作?

#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)

4 个答案:

答案 0 :(得分:3)

任何可以使用单个参数调用的构造函数都被视为implicit conversion constructor。这包括简单的1参数情况和默认参数的使用。

在任何需要X并提供Y的上下文中考虑此转换,并且Y具有这种隐式转换的可能性。请注意,许多其他内置转换也可以作为一种混合(如调整常量,积分和fp促销,转换等)。规则是允许最多一个“用户定义”隐式转换混合

在某些情况下,这可能会非常令人惊讶,因此一般建议是制作任何此类ctors explicit。该关键字使转换成为可能但不是隐式的:您必须使用T()语法来强制转换。

作为一个例子,考虑std::vector有一个ctor采用size_t,设置初始大小。它是明确的 - 否则你的foo(vector<double> const& )函数可能被错误地调用foo(42)。

答案 1 :(得分:0)

这是正确的结果。由于constructor不是explicit - 隐式转换有效(此处One隐式转换为Two)。

one已创建,然后传递给f转换为Two

答案 2 :(得分:0)

编译器必须在堆栈上创建Two实例的副本。当您使用作为类f()(或任何其他)的对象的参数调用One时,编译器会查找类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号) F(美孚)

答案 3 :(得分:0)

Two(const One&) {cout<<"Two(const One&)"<<endl;}构造函数的含义是,您可以随时从Two隐式地构造One值。当您致电f(one)时,它需要一个Two参数,它会被赋予One,因此编译器会将2和2放在一起并说“我将从中创建一个临时Two One并完成对f()的调用“......每个人都会很开心。乌拉!