conditions for automatic generation of default ctor, copy ctor,and default assignment operator (oper

P

puzzlecracker

From my understanding, if you declare any sort of constructors,
(excluding copy ctor), the default will not be included by default. Is
this correct?

class Foo{
public:
Foo(int); // no Foo() is included, i believe.
};



Under which conditions a default copy ctor and default assignment
operator are not included?


Thanks.
 
S

sk_usenet

puzzlecracker said:
From my understanding, if you declare any sort of constructors,
(excluding copy ctor), the default will not be included by default. Is
this correct?

No, even declaring/defining an explicit copy c'tor would restrict compiler
from generating a default constructor.
class Foo{
public:
Foo(int); // no Foo() is included, i believe.

No default constructor would be generated in this case. Default assignment
operator won't be affected.
 
P

puzzlecracker

No, even declaring/defining an explicit copy c'tor would restrict compiler
from generating a default constructor.

What about the reverse - Will declaring an explicit default ctor,
cause a class to generate a default copy constructor?


How is assignment affected? Say we generate an overload version of
assignment operator, will a default be included in the class?


Thanks
 
S

sk_usenet

puzzlecracker said:
What about the reverse - Will declaring an explicit default ctor,
cause a class to generate a default copy constructor?

Yes. Just from compilation perspectives it should be fine (Try it without
defining it).
How is assignment affected? Say we generate an overload version of
assignment operator, will a default be included in the class?

Yes
 
A

Andrey Tarasevich

puzzlecracker said:
What about the reverse - Will declaring an explicit default ctor,

By "explicit" here you probably mean "user-declared". The term
"explicit" has a certain specific meaning when applied to constructors
in C++, you know...
cause a class to generate a default copy constructor?

Again, a problem with terminology. There's no such thing as "default
copy constructor". There's the default constructor. And there's the copy
constructor. Both can be ether user-declared or compiler-declared.

I assume your question is about the compiler-declared copy constructor.
Providing a user-declared default constructor will not really "cause"
anything to happen to compiler-declared copy constructor, i.e. it will
not prevent the compiler from declaring the copy constructor in
situations when you don't declare it yourself.
How is assignment affected? Say we generate an overload version of
assignment operator, will a default be included in the class?

Yes. Regardless of what other assignment operators you might declare, if
you don't declare the copy assignment operator, the compiler will
declare one for you.
 
J

James Kanze

From my understanding, if you declare any sort of
constructors, (excluding copy ctor), the default will not be
included by default. Is this correct?

No. Any user defined constructor, including a copy constructor,
inhibits automatic generation of the default constructor.
class Foo{
public:
Foo(int); // no Foo() is included, i believe.

};
Under which conditions a default copy ctor and default
assignment operator are not included?

A copy constructor is generated any time there is no user
declared copy construtor. A copy assignment operator is
generated any time there is no user declared copy assignment
operator. A copy constructor for a class X is a non-template
constructor having an X&, X const&, X volatile& or X const
volatile& as its first parameter, and having default arguments
for all other parameters, if any. A copy assignment operator is
a non-template assignment operator having an X, X&, X const&, X
volatile& or X const volatile& as parameter. Note that:

-- a member function template template is never considered a
copy constructor or copy assignment operator (and thus will
never prevent the compiler from generating one);

-- you can declare more than one copy constructor or copy
assignment operator; and

-- operator overload resolution is *always* used when deciding
what constructor to call, even when "copying", and operator
overload resolution can choose a constructor which is not a
copy constructor to copy.

Consider:

class C
{
public:
template< typename T >
C( T& other ) ;
} ;

The compiler will generate a C::C( C const& ) copy constructor,
which will participate in operator overload resolution:

C c1 ;
C c2( c1 ) ; // calls the template constructor.
C c3( C() ) ; // calls the compiler generated copy
// constructor.
 
S

sasha

class C
{
public:
template< typename T >
C( T& other ) ;
} ;
C c1 ;
C c2( c1 ) ; // calls the template constructor.
C c3( C() ) ; // calls the compiler generated copy
// constructor.

That's interesting, I didn't know template copy ctor that takes non-
const, supersedes non-template ctor that take const type, when user
passes const type
 
A

Andrey Tarasevich

sasha said:
That's interesting, I didn't know template copy ctor that takes non-
const, supersedes non-template ctor that take const type, when user
passes const type

Sorry, but what you said doesn't seem to make much sense.

Firstly, there's no const type in this example.

Secondly, when user does actually use an initializer of const type, the
constructor that takes a non-const reference will not even qualify as a
viable function. So no, it will not supersede anything. The behavior
will be exactly opposite of what you said.

How did you manage to derive these strange conclusions from the previous
post from James is a mystery to me.
 
J

James Kanze

That's interesting, I didn't know template copy ctor that
takes non- const, supersedes non-template ctor that take const
type, when user passes const type

I don't understand your reasoning. There's not a single const
object in my example. The template constructor is chosen when
the argument is a non-const lvalue, because the instantiation of
the template (C::C(C&)) is a better match. The compiler
generated copy constructor has the signature C::C( C const& )
(in this case), and will be called when the argument is const,
or isn't an lvalue---both case in which the template constructor
couldn't be called.

Note that the compiler generated copy constructor doesn't always
take a const reference---if the class contains a member or has a
base whose copy constructor (user provided) takes a non-const
reference, the the compiler generated copy constructor will also
take a non-const reference. Such cases are (hopefully) rare,
however.
 

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,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top