PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > class instantiation question
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
class instantiation question

Réponse
 
LinkBack Outils de la discussion
Vieux 01/07/2008, 04h16   #1
hill.liu@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut class instantiation question

Hi,

I stuck into this problem that I can't figure it out.
Here is the class definition:

class ctest {
public:
ctest(void) { cout << "ctest default constor" << endl; };
ctest(ctest& c) { cout <<"ctest copy constr" << endl; };
ctest(int a) { cout <<"ctest int constor" <<endl; };

ctest& operator= (ctest& a) { cout << "ctest copy assignment" <<
endl; return *this; };
operator int() { cout << "call operator int()" <<endl; return 20; }
};

int main(void)
{
ctest cc = ctest();
}

And it outputs as following:
ctest default constor
call operator int()
ctest int constor

I wonder why it will invoke "operator int()" and call "constructor
with int as argument".

Thanks
Brad
  Réponse avec citation
Vieux 01/07/2008, 04h24   #2
Elias Salomão Helou Neto
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: class instantiation question

On 1 jul, 00:16, "hill....@gmail.com" <hill....@gmail.com> wrote:
> Hi,
>
> I stuck into this problem that I can't figure it out.
> Here is the class definition:
>
> class ctest {
> public:
> ctest(void) { cout << "ctest default constor" << endl; };
> ctest(ctest& c) { cout <<"ctest copy constr" << endl; };
> ctest(int a) { cout <<"ctest int constor" <<endl; };
>
> ctest& operator= (ctest& a) { cout << "ctest copy assignment" <<
> endl; return *this; };
> operator int() { cout << "call operator int()" <<endl; return 20; }
>
> };
>
> int main(void)
> {
> ctest cc = ctest();
>
> }
>
> And it outputs as following:
> ctest default constor
> call operator int()
> ctest int constor
>
> I wonder why it will invoke "operator int()" and call "constructor
> with int as argument".
>
> Thanks
> Brad


I wonder where is the

return( 0 );

statement.
  Réponse avec citation
Vieux 01/07/2008, 04h37   #3
Darío Griffo
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: class instantiation question

> > ctest(ctest& c) { cout <<"ctest copy constr" << endl; };

You've forgot the const:
ctest(const ctest& c) { cout <<"ctest copy constr" << endl; };

> > ctest& operator= (ctest& a) { cout << "ctest copy assignment" <<


Also up here

ctest& operator= (const ctest& a) { cout << "ctest copy assignment" <<

and here
> > operator int() { cout << "call operator int()" <<endl; return 20; }

operator int()const { cout << "call operator int()" <<endl; return
20; }

I think it's a good question why the compiler thinks that a non const
reference should be a int..
All I did is gave you the practical solution, not the teorical.

> > Brad

>
> I wonder where is the
>
> return( 0 );
>
> statement.


That's not necesary, it's not an error, but it's a good practice not
to forget all the pieces of a program
Darío

  Réponse avec citation
Vieux 01/07/2008, 04h49   #4
Elias Salomão Helou Neto
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: class instantiation question

On 1 jul, 00:24, Elias Salomão Helou Neto <eshn...@gmail.com> wrote:
> On 1 jul, 00:16, "hill....@gmail.com" <hill....@gmail.com> wrote:
>
>
>
> > Hi,

>
> > I stuck into this problem that I can't figure it out.
> > Here is the class definition:

>
> > class ctest {
> > public:
> > ctest(void) { cout << "ctest default constor" << endl; };
> > ctest(ctest& c) { cout <<"ctest copy constr" << endl; };
> > ctest(int a) { cout <<"ctest int constor" <<endl; };

>
> > ctest& operator= (ctest& a) { cout << "ctest copy assignment" <<
> > endl; return *this; };
> > operator int() { cout << "call operator int()" <<endl; return 20; }

>
> > };

>
> > int main(void)
> > {
> > ctest cc = ctest();

>
> > }

>
> > And it outputs as following:
> > ctest default constor
> > call operator int()
> > ctest int constor

>
> > I wonder why it will invoke "operator int()" and call "constructor
> > with int as argument".

>
> > Thanks
> > Brad

>
> I wonder where is the
>
> return( 0 );
>
> statement.


Well, it does not quite solve the problem. In fact, the issue here is
const-correctness, because ctest() must be used as const, but ctest
has ctest& or int as arguments, being the second the only possible the
compiler tryes to find a conversion. The following does not compile:

#include <iostream>

class ctest {
public:
ctest(void) { std::cout << "ctest default constor" <<
std::endl; };
ctest(ctest& c) { std::cout <<"ctest copy constr" <<
std::endl; };
//ctest(int a) { std::cout <<"ctest int constor" <<
std::endl; };

ctest& operator= (ctest& a) { std::cout << "ctest copy
assignment" << std::endl; return *this; };
//operator int() { std::cout << "call operator int()"
<< std::endl; return 20; }

};

int main(void)
{
ctest cc = ctest();
return( 0 );
}

but the following does:

#include <iostream>

class ctest {
public:
ctest(void) { std::cout << "ctest default constor" <<
std::endl; };
ctest(const ctest& c) { std::cout <<"ctest copy
constr" << std::endl; };
ctest(int a) { std::cout <<"ctest int constor" <<
std::endl; };

ctest& operator= (ctest& a) { std::cout << "ctest copy
assignment" << std::endl; return *this; };
operator int() { std::cout << "call operator int()" <<
std::endl; return 20; }

};

int main(void)
{
ctest cc = ctest();
return( 0 );
}

and prints

ctest default constor

only once, because of optimization, I guess.
  Réponse avec citation
Vieux 01/07/2008, 05h15   #5
hill.liu@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: class instantiation question

On Jul 1, 11:49 am, Elias Salomão Helou Neto <eshn...@gmail.com>
wrote:
> On 1 jul, 00:24, Elias Salomão Helou Neto <eshn...@gmail.com> wrote:
>
>
>
> > On 1 jul, 00:16, "hill....@gmail.com" <hill....@gmail.com> wrote:

>
> > > Hi,

>
> > > I stuck into this problem that I can't figure it out.
> > > Here is the class definition:

>
> > > class ctest {
> > > public:
> > > ctest(void) { cout << "ctest default constor" << endl;};
> > > ctest(ctest& c) { cout <<"ctest copy constr" << endl; };
> > > ctest(int a) { cout <<"ctest int constor" <<endl; };

>
> > > ctest& operator= (ctest& a) { cout << "ctest copy assignment" <<
> > > endl; return *this; };
> > > operator int() { cout << "call operator int()" <<endl;return 20; }

>
> > > };

>
> > > int main(void)
> > > {
> > > ctest cc = ctest();

>
> > > }

>
> > > And it outputs as following:
> > > ctest default constor
> > > call operator int()
> > > ctest int constor

>
> > > I wonder why it will invoke "operator int()" and call "constructor
> > > with int as argument".

>
> > > Thanks
> > > Brad

>
> > I wonder where is the

>
> > return( 0 );

>
> > statement.

>
> Well, it does not quite solve the problem. In fact, the issue here is
> const-correctness, because ctest() must be used as const, but ctest
> has ctest& or int as arguments, being the second the only possible the
> compiler tryes to find a conversion. The following does not compile:
>
> #include <iostream>
>
> class ctest {
> public:
> ctest(void) { std::cout << "ctest default constor" <<
> std::endl; };
> ctest(ctest& c) { std::cout <<"ctest copy constr" <<
> std::endl; };
> //ctest(int a) { std::cout <<"ctest int constor" <<
> std::endl; };
>
> ctest& operator= (ctest& a) { std::cout << "ctest copy
> assignment" << std::endl; return *this; };
> //operator int() { std::cout << "call operator int()"
> << std::endl; return 20; }
>
> };
>
> int main(void)
> {
> ctest cc = ctest();
> return( 0 );
>
> }
>
> but the following does:
>
> #include <iostream>
>
> class ctest {
> public:
> ctest(void) { std::cout << "ctest default constor" <<
> std::endl; };
> ctest(const ctest& c) { std::cout <<"ctest copy
> constr" << std::endl; };
> ctest(int a) { std::cout <<"ctest int constor" <<
> std::endl; };
>
> ctest& operator= (ctest& a) { std::cout << "ctest copy
> assignment" << std::endl; return *this; };
> operator int() { std::cout << "call operator int()" <<
> std::endl; return 20; }
>
> };
>
> int main(void)
> {
> ctest cc = ctest();
> return( 0 );
>
> }
>
> and prints
>
> ctest default constor
>
> only once, because of optimization, I guess.


Forget to mention, I use Microsoft C/C++ Optimizing Compiler Version
14.00.50727.42 without any optimization option.
I comment out ctest(int a) and operator int() it still compiles. And
the execution output is
"ctest default constor"

From your reply and my understanding right now, ctest cc = ctest() has
two part. First part is that ctest() will create a temp ctest object
using default constructor. And second part is to create object cc
using copy constructor with that temp ctest as argument. Because that
temp ctest is a const, and my original class definition has no const-
copy constructor; so compiler convert that temp ctest into int and use
ctest(int a) to create object cc.
But why it still compiles after comment out ctest(int a) and operator
int()?
And, after I add const to copy constructor like this: ctest(const
ctest& c) { cout <<"ctest copy constr" << endl; }, why it doesn't
output "ctest copy constr"?
  Réponse avec citation
Vieux 01/07/2008, 06h12   #6
Kai-Uwe Bux
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: class instantiation question

hill.liu@gmail.com wrote:

> On Jul 1, 11:49 am, Elias Salomão Helou Neto <eshn...@gmail.com>
> wrote:
>> On 1 jul, 00:24, Elias Salomão Helou Neto <eshn...@gmail.com> wrote:
>>
>>
>>
>> > On 1 jul, 00:16, "hill....@gmail.com" <hill....@gmail.com> wrote:

>>
>> > > Hi,

>>
>> > > I stuck into this problem that I can't figure it out.
>> > > Here is the class definition:

>>
>> > > class ctest {
>> > > public:
>> > > ctest(void) { cout << "ctest default constor" <<
>> > > endl; }; ctest(ctest& c) { cout <<"ctest copy constr"
>> > > << endl; }; ctest(int a) { cout <<"ctest int constor"
>> > > <<endl; };

>>
>> > > ctest& operator= (ctest& a) { cout << "ctest copy
>> > > assignment" <<
>> > > endl; return *this; };
>> > > operator int() { cout << "call operator int()"
>> > > <<endl; return 20; }

>>
>> > > };

>>
>> > > int main(void)
>> > > {
>> > > ctest cc = ctest();

>>
>> > > }

>>
>> > > And it outputs as following:
>> > > ctest default constor
>> > > call operator int()
>> > > ctest int constor

>>
>> > > I wonder why it will invoke "operator int()" and call "constructor
>> > > with int as argument".

>>
>> > > Thanks
>> > > Brad

>>
>> > I wonder where is the

>>
>> > return( 0 );

>>
>> > statement.

>>
>> Well, it does not quite solve the problem. In fact, the issue here is
>> const-correctness, because ctest() must be used as const, but ctest
>> has ctest& or int as arguments, being the second the only possible the
>> compiler tryes to find a conversion. The following does not compile:
>>
>> #include <iostream>
>>
>> class ctest {
>> public:
>> ctest(void) { std::cout << "ctest default constor" <<
>> std::endl; };
>> ctest(ctest& c) { std::cout <<"ctest copy constr" <<
>> std::endl; };
>> //ctest(int a) { std::cout <<"ctest int constor" <<
>> std::endl; };
>>
>> ctest& operator= (ctest& a) { std::cout << "ctest copy
>> assignment" << std::endl; return *this; };
>> //operator int() { std::cout << "call operator int()"
>> << std::endl; return 20; }
>>
>> };
>>
>> int main(void)
>> {
>> ctest cc = ctest();
>> return( 0 );
>>
>> }
>>
>> but the following does:
>>
>> #include <iostream>
>>
>> class ctest {
>> public:
>> ctest(void) { std::cout << "ctest default constor" <<
>> std::endl; };
>> ctest(const ctest& c) { std::cout <<"ctest copy
>> constr" << std::endl; };
>> ctest(int a) { std::cout <<"ctest int constor" <<
>> std::endl; };
>>
>> ctest& operator= (ctest& a) { std::cout << "ctest copy
>> assignment" << std::endl; return *this; };
>> operator int() { std::cout << "call operator int()" <<
>> std::endl; return 20; }
>>
>> };
>>
>> int main(void)
>> {
>> ctest cc = ctest();
>> return( 0 );
>>
>> }
>>
>> and prints
>>
>> ctest default constor
>>
>> only once, because of optimization, I guess.

>
> Forget to mention, I use Microsoft C/C++ Optimizing Compiler Version
> 14.00.50727.42 without any optimization option.
> I comment out ctest(int a) and operator int() it still compiles. And
> the execution output is
> "ctest default constor"
>
> From your reply and my understanding right now, ctest cc = ctest() has
> two part. First part is that ctest() will create a temp ctest object
> using default constructor. And second part is to create object cc
> using copy constructor with that temp ctest as argument. Because that
> temp ctest is a const, and my original class definition has no const-
> copy constructor; so compiler convert that temp ctest into int and use
> ctest(int a) to create object cc.


That understanding is not entirely correct. The temporary

ctest()

is _not_ const. If ctest had a non-const member function foo(), you could do

ctest().foo()

and the compiler would not complain.

The misconception that temporaries are const stems from the provisions in
[8.5.3/5] that prohibit initializing a non-const reference from a
temporary. Your copy constructor takes its argument as a non-const
reference and since the compiler cannot use the temporary ctest() to
initialize it, it rejects this option.


> But why it still compiles after comment out ctest(int a) and operator
> int()?


It doesn't. You also have to change the copy constructor.

> And, after I add const to copy constructor like this: ctest(const
> ctest& c) { cout <<"ctest copy constr" << endl; }, why it doesn't
> output "ctest copy constr"?


Because the compiler is allowed to optimize the copy constructor call away
even if that changes the observable behavior of the program.


Best

Kai-Uwe Bux
  Réponse avec citation
Vieux 01/07/2008, 06h55   #7
hill.liu@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: class instantiation question

On Jul 1, 1:12 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> hill....@gmail.com wrote:
> > On Jul 1, 11:49 am, Elias Salomão Helou Neto <eshn...@gmail.com>
> > wrote:
> >> On 1 jul, 00:24, Elias Salomão Helou Neto <eshn...@gmail.com> wrote:

>
> >> > On 1 jul, 00:16, "hill....@gmail.com" <hill....@gmail.com> wrote:

>
> >> > > Hi,

>
> >> > > I stuck into this problem that I can't figure it out.
> >> > > Here is the class definition:

>
> >> > > class ctest {
> >> > > public:
> >> > > ctest(void) { cout << "ctest default constor" <<
> >> > > endl; }; ctest(ctest& c) { cout <<"ctest copy constr"
> >> > > << endl; }; ctest(int a) { cout <<"ctest int constor"
> >> > > <<endl; };

>
> >> > > ctest& operator= (ctest& a) { cout << "ctest copy
> >> > > assignment" <<
> >> > > endl; return *this; };
> >> > > operator int() { cout << "call operator int()"
> >> > > <<endl; return 20; }

>
> >> > > };

>
> >> > > int main(void)
> >> > > {
> >> > > ctest cc = ctest();

>
> >> > > }

>
> >> > > And it outputs as following:
> >> > > ctest default constor
> >> > > call operator int()
> >> > > ctest int constor

>
> >> > > I wonder why it will invoke "operator int()" and call "constructor
> >> > > with int as argument".

>
> >> > > Thanks
> >> > > Brad

>
> >> > I wonder where is the

>
> >> > return( 0 );

>
> >> > statement.

>
> >> Well, it does not quite solve the problem. In fact, the issue here is
> >> const-correctness, because ctest() must be used as const, but ctest
> >> has ctest& or int as arguments, being the second the only possible the
> >> compiler tryes to find a conversion. The following does not compile:

>
> >> #include <iostream>

>
> >> class ctest {
> >> public:
> >> ctest(void) { std::cout << "ctest default constor" <<
> >> std::endl; };
> >> ctest(ctest& c) { std::cout <<"ctest copy constr" <<
> >> std::endl; };
> >> //ctest(int a) { std::cout <<"ctest int constor" <<
> >> std::endl; };

>
> >> ctest& operator= (ctest& a) { std::cout << "ctest copy
> >> assignment" << std::endl; return *this; };
> >> //operator int() { std::cout << "call operator int()"
> >> << std::endl; return 20; }

>
> >> };

>
> >> int main(void)
> >> {
> >> ctest cc = ctest();
> >> return( 0 );

>
> >> }

>
> >> but the following does:

>
> >> #include <iostream>

>
> >> class ctest {
> >> public:
> >> ctest(void) { std::cout << "ctest default constor" <<
> >> std::endl; };
> >> ctest(const ctest& c) { std::cout <<"ctest copy
> >> constr" << std::endl; };
> >> ctest(int a) { std::cout <<"ctest int constor" <<
> >> std::endl; };

>
> >> ctest& operator= (ctest& a) { std::cout << "ctest copy
> >> assignment" << std::endl; return *this; };
> >> operator int() { std::cout << "call operator int()" <<
> >> std::endl; return 20; }

>
> >> };

>
> >> int main(void)
> >> {
> >> ctest cc = ctest();
> >> return( 0 );

>
> >> }

>
> >> and prints

>
> >> ctest default constor

>
> >> only once, because of optimization, I guess.

>
> > Forget to mention, I use Microsoft C/C++ Optimizing Compiler Version
> > 14.00.50727.42 without any optimization option.
> > I comment out ctest(int a) and operator int() it still compiles. And
> > the execution output is
> > "ctest default constor"

>
> > From your reply and my understanding right now, ctest cc = ctest() has
> > two part. First part is that ctest() will create a temp ctest object
> > using default constructor. And second part is to create object cc
> > using copy constructor with that temp ctest as argument. Because that
> > temp ctest is a const, and my original class definition has no const-
> > copy constructor; so compiler convert that temp ctest into int and use
> > ctest(int a) to create object cc.

>
> That understanding is not entirely correct. The temporary
>
> ctest()
>
> is _not_ const. If ctest had a non-const member function foo(), you coulddo
>
> ctest().foo()
>
> and the compiler would not complain.
>
> The misconception that temporaries are const stems from the provisions in
> [8.5.3/5] that prohibit initializing a non-const reference from a
> temporary. Your copy constructor takes its argument as a non-const
> reference and since the compiler cannot use the temporary ctest() to
> initialize it, it rejects this option.
>
> > But why it still compiles after comment out ctest(int a) and operator
> > int()?

>
> It doesn't. You also have to change the copy constructor.
>
> > And, after I add const to copy constructor like this: ctest(const
> > ctest& c) { cout <<"ctest copy constr" << endl; }, why it doesn't
> > output "ctest copy constr"?

>
> Because the compiler is allowed to optimize the copy constructor call away
> even if that changes the observable behavior of the program.
>
> Best
>
> Kai-Uwe Bux


Now I know why my original class definition will produce those
outputs.:-)
But I refine class definition like Elias suggested:
class ctest {
public:
ctest(void) { std::cout << "ctest default constor" <<
std::endl; };
ctest(ctest& c) { std::cout <<"ctest copy constr" <<
std::endl; };

ctest& operator= (ctest& a) { std::cout << "ctest copy
assignment" << std::endl; return *this; };

};
I build this successfully under Visual Studio 2005 and "ctest cc =
ctest()" outputs "ctest default constor".
Why is that?
  Réponse avec citation
Vieux 01/07/2008, 09h28   #8
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: class instantiation question

On Jul 1, 5:16 am, "hill....@gmail.com" <hill....@gmail.com> wrote:

> I stuck into this problem that I can't figure it out.
> Here is the class definition:


> class ctest {
> public:
> ctest(void) { cout << "ctest default constor" << endl; };
> ctest(ctest& c) { cout <<"ctest copy constr" << endl; };
> ctest(int a) { cout <<"ctest int constor" <<endl; };
>
> ctest& operator= (ctest& a) { cout << "ctest copy assignment" <<
> endl; return *this; };
> operator int() { cout << "call operator int()" <<endl; return 20; }
>
> };
>
> int main(void)
> {
> ctest cc = ctest();
>
> }
>
> And it outputs as following:
> ctest default constor
> call operator int()
> ctest int constor


> I wonder why it will invoke "operator int()" and call "constructor
> with int as argument".


Because that's what is required by the standard. Because the
source type is the same as the target type, the copy
initialization basically becomes the same as direct
initialization, e.g. as if you'd written

ctest cc( ctest() ) ;

The only constructor which can be called is the one taking an
int, so the compiler converts your expression into an int, using
the user defined conversion operator, and calls it.

Maybe you meant for the copy constructor (and the assignment
operator, while we're at it, although it isn't used in your
example) to take references to const, as is the normal case.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 02h28.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,25841 seconds with 16 queries