【问题标题】:How does constructor conversion work in C++?构造函数转换如何在 C++ 中工作?
【发布时间】:2013-06-20 09:14:40
【问题描述】:

构造函数转换是如何工作的?

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

【问题讨论】:

    标签: c++ constructor implicit-conversion


    【解决方案1】:

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

    在任何需要 X 并提供 Y 的上下文中都会考虑这种转换,并且 Y 具有这种隐式转换的可能性。请注意,许多其他内置转换也可以混合使用(例如调整 const-ness、integral 和 fp 提升、转换等)。规则是最多允许一个“用户定义”隐式转换在混合。

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

    std::vector 为例,它有一个 ctor 采用 size_t,设置初始大小。它是明确的——否则你的foo(vector&lt;double&gt; const&amp; ) 函数可能会被错误地用 foo(42) 调用。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        Two(const One&amp;) {cout&lt;&lt;"Two(const One&amp;)"&lt;&lt;endl;} 构造函数的意思是你可以在任何时候——隐式地——从One 构造一个Two 值。当您调用 f(one) 它需要一个 Two 参数时,它会得到一个 One,因此编译器将 2 和 2 放在一起并说“我将从 One 中创建一个临时的 Two 并完成调用到f()"...每个人都会很高兴。万岁!

        【讨论】:

          【解决方案4】:

          编译器必须在堆栈上创建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(整数) f(Foo)

          【讨论】:

            猜你喜欢
            • 2023-03-25
            • 2018-06-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-19
            • 1970-01-01
            相关资源
            最近更新 更多