Then if I were to write:
A a1 = a2;
Does the copy constructor get called, or the default operator=, or
both? I tried it in MS VC++ 5 and sure enough the copy constructor
gets called. Is this a standard compiler "optimization", or
convention, or what?
--
Regards,
Jeff
Sent via Deja.com http://www.deja.com/
Before you buy.
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
That language construct is called "initialization during declaration".
There are two ways:
A a1 = a2; // a2 is of type A
and
A a1(a2); // a2 is of type A
They are equivalent. And for classes they invoke a copy constructor.
Victor
--
Please remove capital A's from my address when replying by mail
Hi Jeff !
May be this code examples will help You:
class B { ... };
class A
{
...
public:
// Constructor
A() { ... }
// Copy constructor
A(const A& a_obj) { ... }
// Constructor overloading
A(const B& b_obj) { ... }
...
A& operator=(const A& a_src) { ... }
...
};
// Code examples:
A a1; // constructor as: A()
A a2(a1); // copy constructor as: A(a1)
A a3 = a2; // copy constructor as: A(a2)
B b;
A a4(b); // overloaded constructor as: A(b)
A a5 = b; // overloaded constructor as: A(b)
a1 = a5; // operator=(const A&) as: operator=(a5)
a2 = b; // first step -> creating temporary object of class A
// by overloaded constructor as: A(b),
// and next step -> operator=(const A&) as:
operator=(A(b))
~~~ Max
>"Jeff Connelly" <jeff_c...@mgv.com> wrote...
>> I saw something in C++ FAQs (Cline) that confused me. Given this
>> definition:
>> class A
>> {
>> public:
>> A();
>> A(const A&);
>> };
>>
>> Then if I were to write:
>> A a1 = a2;
>>
>> Does the copy constructor get called, or the default operator=, or
>> both? I tried it in MS VC++ 5 and sure enough the copy constructor
>> gets called. Is this a standard compiler "optimization", or
>> convention, or what?
>
>That language construct is called "initialization during declaration".
>
>There are two ways:
> A a1 = a2; // a2 is of type A
>and
> A a1(a2); // a2 is of type A
>
>They are equivalent. And for classes they invoke a copy constructor.
What about
A a1 = A(a2);
?
I like the above syntax since it gets rid of the problem with the
occasional ambiguity between function declarations and constructor
calls.
But from what I could tell from reading the standard, the above is not
guaranteed to not create a temporary. Or am I wrong?
Tom
>
>Does the copy constructor get called, or the default operator=, or
>both? I tried it in MS VC++ 5 and sure enough the copy constructor
>gets called. Is this a standard compiler "optimization", or
>convention, or what?
MS VC++ 5 is entirely correct in its behaviour. Write out 100 times:
'Initialisation is not assignment.'
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
Assuming a2 is of some type from which an A may be constructed, of
course.
--
Martin Fabian http://www.s2.chalmers.se/~fabian/
--
"Cheer up. It may never happen" (Edina Monsoon)
/* Remove NOSPAM from reply-to address to mail me */
>
> B b;
> A a4(b); // overloaded constructor as: A(b)
> A a5 = b; // overloaded constructor as: A(b)
That one definitely requires an accessible copy ctor that has not been
qualified as explicit even though the compiler is allowed to optimise
away the call to it.
>
> a1 = a5; // operator=(const A&) as: operator=(a5)
> a2 = b; // first step -> creating temporary object of class A
> // by overloaded constructor as: A(b),
Which again must not be qualified as explicit.
> // and next step -> operator=(const A&) as:
>operator=(A(b))
>
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
Francis Glassborow wrote:
>
> >Then if I were to write:
> >A a1 = a2;
> ^
> assuming that a2 is of type A (or a cv qualified version) then that is
> NOT and NEVER has been an assignment operator,
I don't even think you need the qualification as to the type of a2. It's
still
copy-initializatoin. a2 of whatever type has to be converted
(implicitly) to
type A and then direct-initialized into a1.
|> In article <8o11r7$vrb$1...@nnrp1.deja.com>, Jeff Connelly
|> <jeff_c...@mgv.com> writes
|> >I saw something in C++ FAQs (Cline) that confused me. Given this
|> >definition:
|> >class A
|> >{
|> >public:
|> > A();
|> > A(const A&);
|> >};
|> >
|> >Then if I were to write:
|> >A a1 = a2;
|> ^
|> assuming that a2 is of type A (or a cv qualified version) then that
|> is NOT and NEVER has been an assignment operator, it is an
|> initaliser in a declarator and is implemented by calling the copy
|> ctor.
Regardless of the type of a2, there is no assignment operator here. An
assignment operator (like any other operator) only occurs in an
expression -- here, we have a declaration with initialization. (We also
have an expression, but the expression is simply "a2".)
--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
|> Victor Bazarov wrote:
|> >
|> <snap>
|> > There are two ways:
|> > A a1 = a2; // a2 is of type A
|> > and
|> > A a1(a2); // a2 is of type A
|> > They are equivalent. And for classes they invoke a copy constructor.
|> But in the case when a2 is _not_ of type A, they are not necessarily
|> equivalent.
I the case where a2 is not of type A, they are not equivalent, period.
In some cases, however, the compiler may, practically speaking, generate
the same code for the two.
|> In the first case, a temporary A may be constructed from a2,
|> and this temporary is then used to copy construct a1. In the second
|> case, the copy constructor need not be invoked at all.
In the second, the copy constructor may not be invoked. This is a very
big difference. In the first, the compiler is allowed to elide the copy
constructor, and most do, but the legality of the program must be
determined as if the copy constructor is invoked. If the class doesn't
have an accessible copy constructor, the first form is illegal, whereas
the second isn't.
|> > B b;
|> > A a4(b); // overloaded constructor as: A(b)
|> > A a5 = b; // overloaded constructor as: A(b)
|> That one definitely requires an accessible copy ctor that has not been
|> qualified as explicit even though the compiler is allowed to optimise
|> away the call to it.
Are you sure? What it definitly requires is that the constructor
A::A(B) not be explicit (whereas the form with () works even if the
constructor is explicit).
Yes, I constructed a very poor sentence, the assumption was needed for
the very last part (copy ctor)
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
Well not absolutely because I do not think we have officially tied down
what it means to make a copy ctor explicit, but when we discussed it
briefly at the most recent J16/WG21 meeting I believe that our general
reaction was that an explicit copy ctor would require exactly that the
compiler could never call it implicitly.
> In article <863djqo...@gabi-soft.de>, ka...@gabi-soft.de writes
> >Are you sure? What it definitly requires is that the constructor
> >A::A(B) not be explicit (whereas the form with () works even if the
> >constructor is explicit).
>
> Well not absolutely because I do not think we have officially tied down
> what it means to make a copy ctor explicit, but when we discussed it
> briefly at the most recent J16/WG21 meeting I believe that our general
> reaction was that an explicit copy ctor would require exactly that the
> compiler could never call it implicitly.
That of course is the question. Pass by value uses the copy ctor. It
is explicit in pass by value. A copy ctor must be present in an
initializer with = form, thus it is explicit. The exception would be
Base b = Derived which could be doing an implicit slice; however, that
is semantically the same as Base b(Derived).
Those are just opinions. When we discussed it on the newsgroup,
explicit on copy ctor was interpreted as anything from meaningless to
prevents slicing to makes it unuasble for anything other than exact
initialization using the () form. I think the only thing that was
agreed upon was that slicing is a conversion which uses the copy
ctor. Explicit prevents implicit conversions and there is usually
no conversion involved in use of a copy ctor.
For all other explicit ctors, there is a way to use them explicitly.
If all uses of the copy ctor are implicit then how does one make it
explicit? Example:
struct B { B () { } explicit B () { } };
struct D : B { };
void f (B);
void g () {
B b;
D d;
f(b); // not allowed?
f(d); // not allowed?
f(B(d)); // still not allowed?
}
It sure would be nice to have an official definition. Implementers
do not seem to know what it means. The only valid advice today is
"don't do that."
John
When we discussed it in a work group at the last meeting the feeling was
that explicit on a ctor should inhibit pass and return by value and
certainly the case where it is part of a chain of conversions. Now the
case where you are initialising an X as a copy of an X& using assignment
syntax still needs tying down.
Of course we only consider things at the first meeting they are raised
and there maybe all sorts of objections next time round.
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
> Of course we only consider things at the first meeting they are raised
> and there maybe all sorts of objections next time round.
Understood. Please do consider how one can use the explicit ctor
explicitely.