Initializer lists and assignment overloading (operator =)

时光总嘲笑我的痴心妄想 提交于 2019-12-12 22:56:46

问题


Does the overloading of the assignment operator propagate to an initializer list?

For example, suppose a class:

class MyClass {
    private:
        std::string m_myString; //std::string overloads operator =
    public:
        MyClass(std::string myString);
}

And a constructor:

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

Will the initializer list work out the assignment operator overload on std::string? And if not, is there a workaround?

Particularly for GCC.


回答1:


I think what you are missing is the difference between assignment and initialization.

Lets look at a simple example with a fundamental type:

int a = 10; // Initialization
a = 1; // Assignment

The above example is simple and not difficult to understand. However, when you get into user-defined types, it is not as simple because objects are constructed.

For example, lets look at 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

The key thing here is operator= means different things in different contexts. It all depends on what is on the left hand side.

  std::string s1 = "Hello"; // Lhs has std::string s1, so this is initialization
  s1 = "Bob"; // Lhs has only s1, so this is assignment

And initializer lists do initialization only (hence the name initializer list).

MyClass::MyClass(std::string myString)
 : m_myString(myString) // Initialization
{
}

Just be aware, when you call operator= in the body of the constructor, you are now doing assignment and not initialization.

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:


I believe it will use the copy constructor rather than the assignment operator.




回答3:


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

Note that you have two copies here: one to initialize the parameter myString, and one to initialize the member m_myString. You don't want that. In C++03, you would take the parameter by const reference:

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

And in C++11, you would take the parameter by value and then manually move it into the member:

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


来源:https://stackoverflow.com/questions/9369529/initializer-lists-and-assignment-overloading-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!