赋值运算符的重载是否会传播到初始化列表?
例如,假设一个类:
class MyClass {
private:
std::string m_myString; //std::string overloads operator =
public:
MyClass(std::string myString);
}
一个构造函数:
MyClass::MyClass(std::string myString)
: m_myString(myString)
{
}
初始化列表是否会解决std::string
上的赋值运算符重载?如果没有,是否有解决方法?
特别是GCC。
答案 0 :(得分:3)
我相信它会使用复制构造函数而不是赋值运算符。
答案 1 :(得分:2)
我认为您缺少的是assignment
和initialization
之间的区别。
让我们看一个基本类型的简单示例:
int a = 10; // Initialization
a = 1; // Assignment
以上示例很简单,不难理解。但是,当您进入用户定义的类型时,它并不那么简单,因为对象是构造的。
例如,让我们看一下std::string
std::string s1("String1"); // Initialization (constructs s1 using constructor)
std::string s2 = s1; // Initialization (constructs s2 using copy constructor)
std::string s3(s2); // Initialization (constructs s3 using copy constructor)
s1 = s2; // Assigns s2 to s1 using assignment operator
这里的关键是operator=
在不同的背景下意味着不同的东西。这一切都取决于左侧的内容。
std::string s1 = "Hello"; // Lhs has std::string s1, so this is initialization
s1 = "Bob"; // Lhs has only s1, so this is assignment
初始化列表仅进行初始化(因此名称为 initializer 列表)。
MyClass::MyClass(std::string myString)
: m_myString(myString) // Initialization
{
}
请注意,当您在构造函数的主体中调用operator=
时,您现在正在进行赋值而不是初始化。
MyClass::MyClass(std::string myString)
{
// m_myString(myString); <-- Error: trying to call like a function
m_myString = myString; // Okay, but this is assignment not initialization
}
答案 2 :(得分:2)
MyClass::MyClass(std::string myString)
: m_myString(myString)
{
}
请注意,此处有两个副本:一个用于初始化参数myString
,另一个用于初始化成员m_myString
。你不希望这样。在C ++ 03中,您将通过const引用获取参数:
MyClass::MyClass(const std::string& myString)
: m_myString(myString)
{
}
在C ++ 11中,您将按值获取参数,然后手动将其移动到成员中:
MyClass::MyClass(std::string myString)
: m_myString(std::move(myString))
{
}