为啥在这里调用构造函数?
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& value = Int(20))
。这些候选人基于排名,而那个特定的候选人获胜。您可以通过 explicit
标记它来删除构造函数:explicit Int(int x_in = 0)
@Eljay 实际上是Int.operator=(Int&& value = Int(20))
获胜。
【参考方案1】:
在类中没有定义赋值运算符operator =( int )
。但是该类有转换构造函数
Int(int x_in = 0)
所以在这个声明中
obj = 20;
调用像Int( 20 )
这样的构造函数将整数值转换为Int
类型的对象,由于编译器生成的隐式移动赋值运算符,可以将其分配给对象obj
。
【讨论】:
@user17732522 你是对的。:)【参考方案2】:由于缺少采用int
的赋值运算符,您的编译器将使用它可以得到的下一个最佳赋值运算符,即隐式声明的移动赋值运算符 (Int::operator=(Int&&)
)。要使用此运算符,需要对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;
;
【讨论】:
以上是关于为啥在这里调用构造函数?的主要内容,如果未能解决你的问题,请参考以下文章