views:

145

answers:

4

I have two copy constructors

Foo(Foo &obj){

}
Foo(Foo *obj){

}

When will the second copy constructor will get called?

+9  A: 

No you don't - you have one copy constructor

Foo( Foo * obj );

is not a copy constructor, and will never be used as such by the C++ compiler. You can of course use it yourself:

Foo a;
Foo b( & a );   // use your constructor

Note also that your real copy constructor should be declared as;

Foo( const Foo & f );

though the lack of const does not prevent it from being a copy constructor.

anon
+2  A: 

The second is not a copy constructor. It is a constructor that gets called when you create a new Foo object, giving a pointer to a Foo as parameter.

Foo foo0;
Foo foo1 = foo0;  // Calls copy constructor
Foo foo2(foo0);   // Calls copy constructor
Foo foo3(&foo0);  // Calls constructor taking a pointer as parameter
Didier Trosset
You could add the case Foo * pfoo = new Foo; Foo foo4(pfoo);
Luc Touraille
+2  A: 

One of your constructors is a copy constructor, the other is just a normal constructor.

The second will be called if you explicitly initialize a Foo from a pointer to Foo or in other situations where an conversion from a pointer to Foo to an r-value Foo is called for, such as argument passing and function returns.

It's usually a bad idea to have such an implicit conversion; it may occur when you don't expect it to and is liable to turn trivial typos from compile errors into unusual behaviour at runtime.

Charles Bailey
+4  A: 

Leaving aside that the second constructor isn't a copy constructor - you actually wanted to know when the second constructor will be called.

The Foo(Foo* obj); constructor is a single parameter constructor - because it hasn't been marked with the explicit keyword, it provides an implicit conversion from Foo* to Foo. It may be called at any time where a Foo* is used in the place of a Foo or const Foo& - if it's being called unexpectedly, that's almost certainly what's happening.

In general, single parameter constructors should either be copy constructors (which other answers have explained) or should be maked explicit. Constructors which provide implicit conversions should be used sparingly.

Joe Gauterin