Temporary & default c'tor

R

RainBow

I understand that a compiler synthesises a default constructor if none
is provided by the user ( of course depending on the situation if
synthesis of such c'tor is actually needed in the program e.g if vptr
is needed, default c'tor must be synthesised by compiler).

In the class Temporary below, there is no reason why a compiler should
synthesise a default c'tor.

class Temporary
{
public:
Temporary(const Temporary& a) { printf("copy ctor of Temporary invoked
\n"); }
Temporary(int a, int b){printf("in user defined ctor\n");}
~Temporary() { printf("in dtor of Temporary\n");}
};

Now, if I write a function like:

Temporary induceTemporaryGeneration()
{
Temporary t(8,9);
return t;
}

I get the output as:
[
in user defined ctor
copy ctor of Temporary invoked
in dtor of Temporary
in dtor of Temporary
]

In this scenario, I know that dtor is called twice because of a
temporary that is created by compiler, but what I dont understand is :
What type of CONSTRUCTOR does compiler use to create this temporary? I
have not provided any default c'tor here so I was hoping that compiler
will give me an error "No default c'tor found in class Temporary", but
this does not happen in Visual Studio 8 VC++ compiler. Why? Why? Why?

I thought of what would be going behind the scene based on the output
generated, and this is what I think might be happening: Please let me
know if my understanding is correct or not.

//Does compiler change it like this?
Temporary induceTemporaryGeneration( const Temporary& aTmp )
{
Temporary t(8,9); // in user defined ctor
aTmp.Temporary::Temporary(t); //COMPILER ADDED?
return t;
}

//Does compiler augment the function like this?
void test_Temporary()
{
Temporary tmp;
tmp.Temporary::Temporary(); //Which constructor will be run on tmp
here?
Temporary f = induceTemporaryGeneration(tmp);
f.Temporary::Temporary(tmp); // copy ctor of Temporary invoked
tmp.Temporary::~Temporary(); // in dtor of Temporary
f.Temporary::~Temporary(); // in dtor of Temporary
}

Thanks for your replies.
~Viren
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

I understand that a compiler synthesises a default constructor if none
is provided by the user ( of course depending on the situation if
synthesis of such c'tor is actually needed in the program e.g if vptr
is needed, default c'tor must be synthesised by compiler).

In the class Temporary below, there is no reason why a compiler should
synthesise a default c'tor.

class Temporary
{
public:
Temporary(const Temporary& a) { printf("copy ctor of Temporary invoked
\n"); }
Temporary(int a, int b){printf("in user defined ctor\n");}
~Temporary() { printf("in dtor of Temporary\n");}
};

Now, if I write a function like:

Temporary induceTemporaryGeneration()
{
Temporary t(8,9);
return t;
}

I get the output as:
[
in user defined ctor
copy ctor of Temporary invoked
in dtor of Temporary
in dtor of Temporary
]

In this scenario, I know that dtor is called twice because of a
temporary that is created by compiler, but what I dont understand is :
What type of CONSTRUCTOR does compiler use to create this temporary?

Your output is quite clear, first an object is created using you user-
defined ctor, then a copy of that one is made using the copy-ctor. Both
of those objects are then destructed. No ctor other than those that you
have defined are used. The copy is made because you are returning t by
value, so a copy is made in the function that called
induceTemporaryGeneration().

Notice that as soon as you define *any* ctor the compiler will refrain
from creating default ones. So if you create a class with just a copy
ctor then you can't create an instance of this class since there's no
normal ctro.
 
D

dave_mikesell

class Temporary
{
public:
Temporary(const Temporary& a) { printf("copy ctor of Temporary invoked
\n"); }
Temporary(int a, int b){printf("in user defined ctor\n");}
~Temporary() { printf("in dtor of Temporary\n");}

};

Now, if I write a function like:

Temporary induceTemporaryGeneration()
{
Temporary t(8,9);
return t;

}

I get the output as:
[
in user defined ctor
copy ctor of Temporary invoked
in dtor of Temporary
in dtor of Temporary
]

In this scenario, I know that dtor is called twice because of a
temporary that is created by compiler, but what I dont understand is :
What type of CONSTRUCTOR does compiler use to create this temporary?

The destructor is being called twice - once in
induceTemporaryGeneration when t goes out of scope, and once in the
calling function when the returned object goes out of scope. The
returned object is a copy of t, generated by the copy constructor you
defined.
 
S

Salt_Peter

I understand that a compiler synthesises a default constructor if none
is provided by the user ( of course depending on the situation if
synthesis of such c'tor is actually needed in the program e.g if vptr
is needed, default c'tor must be synthesised by compiler).

In the class Temporary below, there is no reason why a compiler should
synthesise a default c'tor.

class Temporary
{
public:
Temporary(const Temporary& a) { printf("copy ctor of Temporary invoked
\n"); }
Temporary(int a, int b){printf("in user defined ctor\n");}
~Temporary() { printf("in dtor of Temporary\n");}

};

Now, if I write a function like:

Temporary induceTemporaryGeneration()
{
Temporary t(8,9);
return t;

}

I get the output as:
[
in user defined ctor
copy ctor of Temporary invoked
in dtor of Temporary
in dtor of Temporary
]

In this scenario, I know that dtor is called twice because of a
temporary that is created by compiler, but what I dont understand is :
What type of CONSTRUCTOR does compiler use to create this temporary? I
have not provided any default c'tor here so I was hoping that compiler
will give me an error "No default c'tor found in class Temporary", but
this does not happen in Visual Studio 8 VC++ compiler. Why? Why? Why?

The compiler generates a local using your parametized ctor and then
returns a copy by value. No other construction takes place. A copy
ctor is a constructor (and therefore will eventually induce
destruction). Try it without invoking the copy ctor.

Temporary induceTemporaryGeneration()
{
return Temporary(8,9);
}
I thought of what would be going behind the scene based on the output
generated, and this is what I think might be happening: Please let me
know if my understanding is correct or not.

//Does compiler change it like this?
Temporary induceTemporaryGeneration( const Temporary& aTmp )
{
Temporary t(8,9); // in user defined ctor
aTmp.Temporary::Temporary(t); //COMPILER ADDED?
no

return t;

How is this value t returned? answer: by copy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top