wfbarksdale
wfbarksdale

Reputation: 7606

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.

Upvotes: 5

Views: 3438

Answers (4)

Greg Hewgill
Greg Hewgill

Reputation: 994817

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.

Upvotes: 9

cpx
cpx

Reputation: 17577

When you have an implicit constructor, you are allowed to do either:

class Example{
  public:
  Example(int x = 0):x(myX){} ; // use initialization list
  private:
     int myX;
};

Example example3(5); // ok
Example example3 = 5; // ok

Note that, the constructor that I defined also serves as a default constructor.

To be more specific, constructor style in example 3 is usually a case when your constructor is explicit.

class Example{
  public:
  explicit Example(int x = 0):x(myX){} ; // use initialization list
  private:
     int myX;
};

Example example3(5); // ok
Example example3 = 5; // not allowed

You might want to read this FAQ for more information on the use of initialization list in constructor.

Upvotes: 0

vishakvkt
vishakvkt

Reputation: 864

Doing both

className Object = className(10);
className Object(10);

I believe are actually equivalent. Its just personal preference.

Using new to create the object on the other hand besides allocating on the heap, actually returns a pointer to the created object.

Example* example1 = new Example(2);

Speaking about deletion, all of them will call the same class destructor .

Upvotes: 0

tibur
tibur

Reputation: 11636

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.

Upvotes: 2

Related Questions