Afficher un message
Vieux 01/07/2008, 07h12   #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
 
Page generated in 0,09100 seconds with 9 queries