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:

result1

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

      

the result is shown below: result2

I don't understand why it doesn't call the copy assignment, what is the process in this case?

+3


source to share


2 answers


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.

+4


source


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 is other

not T

or derived fromT

, or if T

is a non-class type, but the type other

is a class type, user-defined sequences of conversions that can convert from another type to T

(or to a type derived from T

if T

- 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.

+2


source







All Articles