Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object that initializes to itself in C++

For example, I've the code:

class test{
    public:

    test(){
        cout<<endl<<"TEST";
    }

    void another(){
        cout<<endl<<"Another";
    }

};

int main(){
    test chk = chk;
    chk.another();
}

Here, I've done an initialization of newly created object of type test to itself.

Does such initialization serve special purpose, does such initialization do anything otherwise than initializing test chk; instead of test chk = chk;?

I understand that the constructor cannot be called if the object is initialized to itself, but why?

I would like to know more about such initialization of an object to itself.

like image 979
zLeon Avatar asked Sep 01 '25 17:09

zLeon


2 Answers

You are allowed to write:

test chk = chk;

[basic.scope.declarative]/p1

The potential scope of the first j begins immediately after that j

An implicit copy constructor is thus invoked. You might have used your own to perform some additional initialization:

test(const test&) {
  cout << endl << "copy ctor";
}

Keep in mind that this isn't a good practice and it might even lead to undefined behavior under some circumstances and Clang always issues a -Wuninitialized warning.

like image 169
Marco A. Avatar answered Sep 04 '25 07:09

Marco A.


I modified your code a bit and hope you can catch the point:

class test{
    public:
        test(){ cout<<endl<<"TEST"; }

        test(const test& in)
        {   
            if ( this == &in)
            {   
                cout<<endl<<"Self init";
            }
            cout<<endl<<"Copy ctor";
        }

        void another(){ cout<<endl<<"Another"; }
};  

int main(){
    test chk = chk;
    chk.another();
    cout<<endl;
}  

If you now call your code you will get the following output:

Self init
Copy ctor
Another

One remark to your cout<<endl statements. You last output are hidden because there is no endl after the last output. cout is buffered which means here that it will only write to your console after the next endl or the buffer is full. So it is even better to write: cout<<"something"<<endl;

To the code and the init:

If you take the address of the input object in your copy constructor you can check if you do a copy to yourself. That is good practice, because you need a own copy constructor if you have allocated memory which can't be copied with the default constructor. As you can see from my example, the address of this and in is the same which means the copy constructor want to copy to itself which is typically wrong if not handled in a special way!

For your testcase the behaviour is simply that your object is not initialized, because you copy an uninitialzed object to itself which ends up in a uninitialized object. This is never what you want and clang reports a warning.

like image 37
Klaus Avatar answered Sep 04 '25 06:09

Klaus