问题
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