【问题标题】:About conversion constructor and assignment operator关于转换构造函数和赋值运算符
【发布时间】:2014-02-17 09:34:32
【问题描述】:
foo = int 之类的操作是如何由foo(int)(转换构造函数)和foo::operator=(int)(重载赋值运算符)完成的?什么时候调用一个而不是另一个(也许一个是初级的)?
#include <iostream>
class foo
{
public:
foo(){}
foo(int r_value)
{
std::cout << "\nfoo::foo(int)\n";
}
void operator=(int r_value)
{
std::cout << "\nfoo::operator=(int)\n";
}
};
int main()
{
foo f;
f = 57;
return 0;
}
上面的代码使operator=(int) 在两者都存在时运行,如果operator=(int) 被注释(或相反),则foo(int) 运行。
【问题讨论】:
标签:
c++
constructor
operator-overloading
operator-keyword
assignment-operator
【解决方案1】:
这是基本的重载分辨率。两种重载都是可行的:
将57 绑定到foo::operator=(int)(完全匹配)
通过转换构造函数将57隐式转换为foo,并将临时foo对象绑定到隐式定义的foo::operator=(foo const &)。
由于后者比前者需要更多的转换,因此匹配度较差,因此选择了前者的重载。
您仍然可以通过显式实现第二次调用:
f = foo(57); // binds perfectly to foo::operator=(foo const &)
重载解决的全套规则相当长且涉及,但在像这样的个别情况下,答案是直截了当的。不过,请参阅 13.3 ([over.match]) 了解完整的血腥细节。
【解决方案2】:
有区别:
foo a = 10;
致电foo::foo(int)
foo a;
a = 10;
在a 中调用foo::operator=(int)
【解决方案3】:
两种实现方式不同。第一个是构造函数,第二个是赋值。用例各不相同,每个用例都会根据用例相应地调用。
用例
构造函数被称为foo::foo(int)
foo f = 57;
分配被称为foo::operator=(int)
foo f;
f = 57;
注意
在上述用例和您的示例中使用赋值有更多开销,因为它与赋值一起调用了默认构造函数。
【解决方案4】:
为此声明
f = 57;
编译器首先考虑所有函数 operator =。有两个这样的函数:由您显式定义的和由编译器隐式定义的复制赋值运算符。第一个是最合适的功能。所以才叫。
如果你要注释这个赋值运算符,那么编译器只有一个函数运算符 =。它是隐式定义的复制赋值运算符。但不能直接应用。因此编译器寻求一种将提供的参数转换为类型 foo 的方法。它可以通过调用转换构造函数来做到这一点。