Reputation: 7606
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
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
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
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
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