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。

+3

赋值操作符与什么有关?一个对象只能通过构造函数初始化;如果调用操作符被调用,那只是因为你已经有一个对象实例。 – ildjarn 2012-02-20 22:43:55

+0

@ildjarn老实说,我是初学者列表的新手。我的理由是,因为它将取代构造函数(赋值)主体中的'm_myString = myString;',所以在初始化程序列表中有一个* sorts *属性。 – MPelletier 2012-02-20 22:47:00

+0

这是因为如果你从构造函数初始化列表中省略了'm_myString(myString)',那么隐含地是'm_myString()'(因为'std :: string'有一个不平凡的构造函数),所以你仍然可以分配给一个默认构造的对象。 : - ] – ildjarn 2012-02-20 22:48:26

回答

2

我认为你缺少的是assignmentinitialization之间的差异。

让我们看看一个简单的例子有一个基本类型:

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 
} 
3

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

2
MyClass::MyClass(std::string myString) 
: m_myString(myString) 
{ 
} 

请注意,您在这里有两个副本:一个初始化参数myString,以及一个用来初始化成员m_myString。你不想那样。在C++ 03,则可以通过将常量引用采取参数:

MyClass::MyClass(const std::string& myString) 
: m_myString(myString) 
{ 
} 

而在C++ 11,则可以通过将值手动取参数,然后将其移动到构件:

MyClass::MyClass(std::string myString) 
: m_myString(std::move(myString)) 
{ 
}