I defined a class named String, and I declare a String object using = assignment to initialize it, but I have some questions about the process behind it. Let's see the code:
class String{
public:
String() :str(""){ cout << "default constructor" << endl; }
String(int n);
String(const char *p);
String(const String &x) :str(x.str)
{
cout << "copy constructor" << endl;
}
String& operator=(const String &x)
{
str = x.str;
cout << "operator =" << endl;
return *this;
}
string getStr() const
{
return str;
}
private:
string str;
};
ostream& operator<<(ostream &o,const String &x)
{
o << x.getStr();
return o;
}
String::String(int n)
{
stringstream ss;
ss << n;
ss >> str;
ss.clear();
ss.str("");
cout << "String(int n)" << endl;
}
String::String(const char *p)
{
str = *p;
}
int _tmain(int argc, _TCHAR* argv[])
{
String s6;
s6 = 10;
cout << s6 << endl;
return 0;
}
the result is shown below:
well, this is understandable, first call the default constructor, then call String::String(int n) constructor, at last call copy assignment. Then I modify the main function like this:
int _tmain(int argc, _TCHAR* argv[])
{
String s6=10;
cout << s6 << endl;
return 0;
}
I can't understand why it doesn't call copy assignment, what's the process behind it in this case?
You're confusing assignment and initialization.
String s6=10;
is not assignment, but initialization; more precisely, copy intialization .
1) when a named variable (automatic, static, or thread-local) of a non-reference type
T
is declared with the initializer consisting of an equals sign followed by an expression.
So s6
is intialized/constructed by the appropriate constructor, ie String::String(int)
, no assignment here.
This is not an assignment, this is copy initialization .
T object = other;
(1)...
If
T
is a class type , and the cv-unqualified version of the type ofother
is notT
or derived fromT
, or ifT
is non-class type, but the type ofother
is a class type, user-defined conversion sequences that can convert from the type of other toT
(or to a type derived fromT
ifT
is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion , which is a prvalue temporary (until C++17) prvalue expression (since C++17) if a converting constructor was used, is then used to direct-initialize the object.
In your situation T object = other
transforms to T object(T(other))
( direct initialization ). But
The last step is usually optimized out and the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used. (until C++17)
The last words selected explain why copy constructor was not called during direct initialization.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.