=
运算符时,编译器如何知道
使用构造函数?#include <string>
class Person
{
public:
std::string name;
Person(const char* fullName) : name(fullName) {}
};
int main()
{
Person p1("Jibel Sadeghi"); // This is ok because we declared the constructor with a const char*
/* When we didn't overload the '=' operator for 'const char*',
how the next lines don't have any errors? */
p1 = "Ben Sadeghi";
}
构造函数不是只在定义变量时调用吗?
不。创建对象(类的实例)时使用构造函数。
该对象可以保存在变量中,或数组的元素中,或动态分配的,或(如果您在这里有)临时对象中。
当我们没有定义任何 = 运算符时,编译器如何知道使用构造函数?
你的类有默认的复制赋值运算符,带有签名
Person& Person::operator=(const Person& assign_from);
和默认的移动赋值运算符,带签名
Person& Person::operator=(Person&& move_assign_from);
当编译器尝试编译时
p1 = "Ben Sadeghi";
它发现它需要
Person::operator=()
,查看所有候选者(有默认的两个,因为你没有提供任何),并且对于每个候选者,它尝试将实际参数转换为形式参数的类型。
对于复制赋值,形式参数的类型为
const Person&
,实际参数的类型为const char[12]
,并且有一个隐式构造函数能够执行转换。所以可以调用 Person::Person(const char*)
,然后调用 Person& Person::operator=(const Person&)
。
对于移动赋值,形式参数的类型为
Person&&
,实际参数的类型为const char[12]
,并且有一个隐式构造函数能够执行转换。所以可以调用 Person::Person(const char*)
,然后调用 Person& Person::operator=(Person&&)
。
Person&&
参数比const Person&
更适合临时人员,因此最终选择了Person::Person(const char*)
后跟Person& Person::operator=(Person&&)
的序列。