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

How does constructor conversion work in C++?

本文关键字:C++ 工作 转换 构造函数      更新时间:2023-10-16

构造函数转换如何工作?

#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。这包括简单的 1 参数情况和默认参数的使用。

在任何需要 X 并给定 Y 的上下文中都会考虑此转换,并且 Y 具有这种隐式转换的可能性。 请注意,许多其他内置转换也混合使用(例如调整恒常性、积分和 fp 促销、转换等(。 规则是,混合中最多允许一个"用户定义"的隐式转换。

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

例如,考虑std::vector具有 ctor size_t,设置初始大小。它是显式的 -- 否则你的foo(vector<double> const& )函数可能会被错误地调用 foo(42(。

这是

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

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

Two(const One&) {cout<<"Two(const One&)"<<endl;}构造函数的意思是,您可以随时从One隐式构造Two值。 当你调用f(one)它想要一个Two参数时,它被赋予了一个One,所以编译器将 2 和 2 放在一起,并说"我将从One进行临时Two并完成对f()的调用"......每个人都会很高兴。 万岁!

编译器

必须在堆栈上创建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); 
} ///:~

输出将是:福(整数(f(Foo(