Originally posted by: arcain
class X {
// ...
public:
// ...
X(int);
X(const X&);
~X();
};
X f(X);
void g()
{
X a(1);
X b = f(X(2));
a = f(a);
}
The line we're considered about is:
X b = f(X(2));
f takes a variable of type X as its parameter, so we construct a temporary X (constructed with a value of 2).
We can drop the assignment and end up with:
f(X(2));
Which is still valid C++..
in fact we can drop the function call too, so that we just have:
X(2)
and still have valid C++, and we know this constructs a temporary X, right?
If we move that into X's constructor.. what does it do? The meaning of that statement doesn't change, and it still creates a temporary X.
How do I know this? Because it bit me in the ass a couple months ago. It may work for you with your compiler (some compilers "help" you by initializing uninitialized variables to 0 when building in debug mode), but did not work for me under GCC.
In
external function f, the call "X(2) indeed creates a temporary object.
In ANY CONSTRUCTOR of CLASS X, the call "X(2)" should invoke the CURRENT OBJECT's constructor matching the signature of "X(2)."
If it were to create a TEMPORARY OBJECT, you wouldn't be able to control which base constructors get called in derived classes.
Take a look at this example which comes from
this list of C++ Constructor/Destructor TIPS
Note 1: In the aformentioned examples, the term "ctor" is short for constructor, "dtor" for destructor.
Note 2: In the aformentioned example, all constructors being called from other constructors are being invoked from the "initializer list" section of each calling constructor, not the constructor body (i.e. not inside the "{}" of the constructor). Perhaps this makes a difference, but I'm not sure of that.
Here's a simple program which should resolve this debate:
#include <iostream.h>
class X
{
public:
X()
{
cout << "*this() is being constructed:\t" << this << endl;
X(1); // Invoke constructor X(int i) -or- Construct a temporary object X???
}
X(int i)
{
cout << "*this(" << i << ") is being constructed:\t" << this << endl;
}
~X()
{
cout << "*this is being destroyed:\t" << this << endl;
}
};
int main(void)
{
X objX; // Construct a single object X
return 0;
}
If what I'm claiming is correct, the output will be:
*this is being constructed: <address value #1>
*this(1) is being constructed: <address value #1>
*this is being destroyed: <address value #1>
If what you're claiming is correct, the output will be:
*this is being constructed: <address value #1>
*this(1) is being constructed: <address
value #2>
*this is being destroyed: <address
value #2>
*this is being destroyed: <address value #1>
If the output matches your claim, make the following code change and see if it results in my claim's output:
X() : X(1) // Invoke constructor X(int i) in the initializer list
{
cout << "The address of *this() is: " << this << endl;
}
P.S. If I had a C++ compiler installed, I'd have tested this already. I recently re-formatted and re-installed my OS. As such I haven't gotten around to re-installing a compiler yet.