C ++ what process when declaring a custom class object with = assign to initialize?
I have defined a class called String and I am declaring a String object using = assign to initialize it, but I have some questions about this process. Look at 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:
Ok, that's clear, call the default constructor first, then call String :: String (int n) constructor, on the last copy assignment of the call. Then I change the main function like this:
int _tmain(int argc, _TCHAR* argv[])
{
String s6=10;
cout << s6 << endl;
return 0;
}
I don't understand why it doesn't call the copy assignment, what is the process in this case?
source to share
You are confusing assignment and initialization.
String s6=10;
is not an assignment, but an initialization; more precisely, copy intialization .
1) when a named variable (automatic, static, or thread-local) of non-reference type is
T
declared with an initializer consisting of an equal sign followed by an expression.
So, it is s6
initialized / built by the corresponding constructor, i.e. String::String(int)
, there is no destination here.
source to share
This is not an assignment, this is a copy initialization .
T object = other;
(1)...
If
T
is a class type and the cv-unqualified version of the type isother
notT
or derived fromT
, or ifT
is a non-class type, but the typeother
is a class type, user-defined sequences of conversions that can convert from another type toT
(or to a type derived fromT
ifT
- class type and conversion function available) and the best choice is chosen with overload resolution. Conversion result , which is a temporary expression prvalue (before C ++ 17) prvalue (since C ++ 17), if conversion constructor was used , is used for direct conversion, initialize object.
In your situation, T object = other
converts to T object(T(other))
( direct initialization ). But
The last step is usually optimized and the result of the conversion is created directly in the memory allocated for the target object, but the corresponding constructor (move or copy) is required to be available, although not used, (before C ++ 17)
The last words chosen explain why the copy constructor was not called during direct initialization.
source to share