简体   繁体   中英

C++ what's the process when declaring a user-defined class object using = assignment to initialize?

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:

RESULT1

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

the result is shown below: RESULT2

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 of other is not T or derived from T , or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM