为啥在这里调用构造函数?

Posted

技术标签:

【中文标题】为啥在这里调用构造函数?【英文标题】:why the constructor is getting called here?为什么在这里调用构造函数? 【发布时间】:2021-12-29 12:34:59 【问题描述】:

我对以下代码有疑问。在主函数中会发生什么时行:obj = 20;被执行。我不明白为什么它调用构造函数?谁能解释一下?

#include <iostream>
#include <string>
using namespace std;
class Int 
    int x;
  
public:
    Int(int x_in = 0)
        : x x_in 
    
        cout << "Conversion Ctor called" << endl;
    
    operator string()
    
        cout << "Conversion Operator" << endl;
        return to_string(x);
    
;
int main()

    Int obj(3);
    string str = obj;
    obj = 20;
    string str2 = static_cast<string>(obj);
    obj = static_cast<Int>(30);
    return 0;

【问题讨论】:

编译器会列出Int.operator=(int) 的可能候选对象,其中之一是Int.operator=(Int const&amp; value = Int(20))。这些候选人基于排名,而那个特定的候选人获胜。您可以通过 explicit 标记它来删除构造函数:explicit Int(int x_in = 0) @Eljay 实际上是Int.operator=(Int&amp;&amp; value = Int(20)) 获胜。 【参考方案1】:

在类中没有定义赋值运算符operator =( int )。但是该类有转换构造函数

Int(int x_in = 0)

所以在这个声明中

obj = 20;

调用像Int( 20 )这样的构造函数将整数值转换为Int类型的对象,由于编译器生成的隐式移动赋值运算符,可以将其分配给对象obj

【讨论】:

@user17732522 你是对的。:)【参考方案2】:

由于缺少采用int 的赋值运算符,您的编译器将使用它可以得到的下一个最佳赋值运算符,即隐式声明的移动赋值运算符 (Int::operator=(Int&amp;&amp;))。要使用此运算符,需要对Int 对象的右值引用,编译器使用构造函数Int::Int(int) 创建该对象,即编译器将obj = 20; 视为

obj.operator=(Int(20));

要查看这里发生了什么,您可以自己实现移动赋值运算符,以便在执行赋值运算符时将某些内容打印到控制台:

class Int

...
public:
...


    Int& operator=(Int&& other)
    
        std::cout << "move assignment of Int, new value: " << other.x << '\n';
        x = other.x;
        return *this;
    

    // the following members are only declared to make sure the available
    // constructors/operators are the same as in the original version of the code
    Int(Int&&) = default;
    Int& operator=(Int const&) = default;
    Int(Int const&) = default;
;

【讨论】:

以上是关于为啥在这里调用构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在malloc中不调用构造函数? [复制]

为啥在malloc中不调用构造函数? [复制]

为啥在我的代码中调用复制构造函数而不是移动构造函数?

子类为啥要调用父类的构造函数

为啥隐式复制构造函数调用基类复制构造函数而定义的复制构造函数不调用?

为啥在 C++ 中调用原始类型的构造函数是合法的?