Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Details of C++ Constructor Syntax

This is almost a duplicate question, but I really didn't understand the answer given for the other one, so I am going to try again:

I am learning C++ and I an trying to understand the various options for creating and using constructors. So my first question is what is the difference between these two object creations:

 class Example{
      Example(int x){myX = x} ;
      private:
         int myX;
 }

Then In my main method:

 Example example1 = new Example(5);
 Example example2 = Example(5);
 Example example3(5);

I know that using new will give me a dynamically allocated object, that I will later need to delete. And that the example2 will be allocated on the stack and shouldn't need to be deleted. But I don't really understand when, or why, to use the constructor style of example3. any help involving minimal jargon would be very greatly appreciated because thats why I can't seem to understand this elsewhere. Thanks very much in advance for any light you guys might be able to shed on this for me.

like image 721
wfbarksdale Avatar asked Dec 22 '22 07:12

wfbarksdale


2 Answers

The two declarations

Example example2 = Example(5);
Example example3(5);

are equivalent. Although the first one looks like it might create an object and then invoke the copy constructor, most compilers will simply create the example2 object in place.

The decision about when to choose which of the above styles to use is largely a matter of taste.

Here's a complete example program to demonstrate:

#include <iostream>

using namespace std;

class Test {
public:
    Test(int x): X(x) {
        cout << "constructor " << X << endl;
    }
    Test(const Test &rhs): X(rhs.X) {
        cout << "copy " << X << endl;
    }
    Test &operator=(const Test &rhs) {
        X = rhs.X;
        cout << "assign " << X << endl;
        return *this;
    }
private:
    int X;
};

int main()
{
    Test t1 = Test(1);
    Test t2(2);
    t2 = t1;
}

and the output (gcc 4.2.1, OS X Lion):

constructor 1
constructor 2
assign 1

Notice how the assignment operator is called only for t2 = t1 (as expected), but the copy constructor is not called at all. (However, as Dennis Zickefoose notes in the comments, a copy constructor must be accessible. Try making the copy constructor private in the above example, and the compiler should refuse to compile it.)

EDIT: Note that gcc actually has an option that controls this behaviour:

    -fno-elide-constructors
        The C++ standard allows an implementation to omit creating a
        temporary which is only used to initialize another object of the
        same type.  Specifying this option disables that optimization, and
        forces G++ to call the copy constructor in all cases.
like image 164
Greg Hewgill Avatar answered Jan 04 '23 22:01

Greg Hewgill


Example example1 = new Example(5);

This one won't compile since new Example(5) returns a pointer over an Example. The correct usage is Example * example1 = new Example(5). Needs to be deleted afterward.

Example example2 = Example(5);

This one creates a temporary Example instance and copy it to example2 using (in your case) the default copy constructor.

Example example3(5);

This one creates an instance of Example on the stack and call your constructor.

like image 35
tibur Avatar answered Jan 04 '23 23:01

tibur