简体   繁体   中英

When is a c++ constructor not called?

I have a situation where no constructor appears to be called:

#include <iostream>

using namespace std;

int main ()
{
    class yoyo
    {
        public:
        int i;
        yoyo()
        {
            i = 0;
            cout << "defaultly initialized to 0" << endl;
        }
        yoyo (int j) : i(j)
        {
            cout << "initialized to " << j << endl;
        }
    };

    int i;

    yoyo a;
    cout << "Hello1, i: " << a.i << endl;

    yoyo b(5);
    cout << "Hello2, i: " << b.i << endl;

    yoyo c = b;                                   /* 1 */
    cout << "Hello3, i: " << c.i << endl;

    return 0;
}

Output is:

defaultly initialized to 0
Hello1, i: 0
initialized to 5
Hello2, i: 5
Hello3, i: 5

(Note: nothing between Hello2 and Hello3)

If I change the program to read as follows:

#include <iostream>

using namespace std;

int main ()
{
    class yoyo
    {
        public:
        int i;
        yoyo()
        {
            i = 0;
            cout << "defaultly initialized to 0" << endl;
        }
        yoyo (int j) : i(j)
        {
            cout << "initialized to " << j << endl;
        }
    };

    int i;

    yoyo a;
    cout << "Hello1, i: " << a.i << endl;

    yoyo b(5);
    cout << "Hello2, i: " << b.i << endl;

    yoyo c; c = b;                                  /* 1 */
    cout << "Hello3, i: " << c.i << endl;

    return 0;
}

(The only difference is in he line marked by /* 1 */)

The output now is:

defaultly initialized to 0
Hello1, i: 0
initialized to 5
Hello2, i: 5
defaultly initialized to 0
Hello3, i: 5

Now there is a constructor call between Hello2 and Hello3. My question is, why is there no (visible) constructor call in the first case?

In the case of

yoyo c = b;

it's the copy constructor that is called.

And in the case of

yoyo c; c = b;

it's the copy assignment operator that is called.

If you don't provide any of them, the compiler will generate default versions for you.


If you want to create your own copy constructor, it could look like this:

yoyo(const yoyo& other)
    : i(other.i)
    { std::cout << "copy constructor initialized\n"; }

The copy assignment operator looks like this:

yoyo& operator=(const yoyo& other)
    {
        i = other.i;
        return *this;
    }

Both of them defined inside the class definition of course.

In the first case:

yoyo c = b;   

calls the copy constructor , which the compiler generates for you implicitly in this case.

 yoyo c = b; 

This is referred to as copy-initialization ; the compiler-generated copy constructor will be called and c will be initialized with that copy. Also, the default constructor of c will be called.

c = b;

Here, this is not initialization, this is assignment. The compiler-generated assignment operator will be invoked on that line.

in your code,

yoyo c=b will call copy constructor.if you want to see it being called,you have to define it explicitely.

eg:

yoyo(const yoyo& obj)
{
   this->i=obj.i;  cout<<"copy constructor"<<endl;
}

in the second case it will call constructor and then the assignment operator

yoyo c; //constructor
c = b;  //assignment operator for which only copying occurs

you can overload assignment operator as below

yoyo& operator=(yoyo& obj)
{
    i = obj.i;
    cout << "assignment operator" << endl;
}

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