1

赋值运算符的重载是否会传播到初始化列表?

例如,假设一个类:

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。

4

3 回答 3

3

我相信它将使用复制构造函数而不是赋值运算符。

于 2012-02-20T22:42:47.600 回答
3

我认为您缺少的是 和 之间的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

初始化器列表仅进行初始化(因此名称初始化器列表)。

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
}
于 2012-02-20T23:32:40.657 回答
2
MyClass::MyClass(std::string myString)
 : m_myString(myString)
{
}

请注意,这里有两份副本:一份用于初始化 parameter myString,一份用于初始化 member 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))
{
}
于 2012-02-21T08:31:12.103 回答