【问题标题】: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)) 获胜。

标签: c++ constructor type-conversion typecasting-operator


【解决方案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;
};

【讨论】:

    猜你喜欢
    • 2015-11-04
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多