[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Avoid automatic copy constructor generation

Marcel Müller

10/25/2008 7:03:00 PM

Hi,

is there a way to avoid the automatic copy constructor generation. I do
not want the object to be non-copyable. I simply do not want that
copying is done by the default copy constructor. But there is a
constructor that accepts the base class. This one should be used for
copying.

In fact i have a set of classes with a common abstract base. The
implementations do not have own data members. They only implement
different functionality. But is makes sense to do assignments and copy
construction between these set of types. This effectively changes the
functionality depending on the current type.


class ContainerBase
{ // ...
};

class Container1
: public ContainerBase
{ // no own data members!
public:
Container1()
{}
Container1(const ContainerBase& r)
: ContainerBase(r)
{}
Container1& operator=(const ContainerBase& r)
{ ContainerBase::operator=(r); return *this; }
};

class Container2
: public ContainerBase
{ // no own data members!
public:
Container2()
{}
Container2(const ContainerBase& r)
: ContainerBase(r)
{}
Container2& operator=(const ContainerBase& r)
{ ContainerBase::operator=(r); return *this; }
};


int main()
{ Container1 c1;
Container2 c2 = c1; // OK
Container1 c3 = c1; // Wrong! Invokes Container1(const Contarine1& r)
return 0;
}


Of course, I could implement the copy constructors to do the same thing
as the constructor from const ContainerBase&. But this is really
unneeded redundancy. And the copy constructor is much more complicated
in the real application than in this small example. Furthermore the auto
generated copy constructor is unusable. It has undefined behavior
because of some special internal storage dependencies. It also has to do
with multiple inheritance, so I could not move the code to a member
function either.

Is there a way to avoid the required redefinition of the copy
constructor for each class?


Marcel
34 Answers

Juha Nieminen

10/25/2008 7:33:00 PM

0

Marcel Müller wrote:
> is there a way to avoid the automatic copy constructor generation.

Yes: Implement your own copy constructor. That will make the compiler
to not to create a default one.

Kai-Uwe Bux

10/25/2008 7:41:00 PM

0

Marcel Müller wrote:

> Hi,
>
> is there a way to avoid the automatic copy constructor generation. I do
> not want the object to be non-copyable. I simply do not want that
> copying is done by the default copy constructor. But there is a
> constructor that accepts the base class. This one should be used for
> copying.
>
> In fact i have a set of classes with a common abstract base. The
> implementations do not have own data members. They only implement
> different functionality. But is makes sense to do assignments and copy
> construction between these set of types. This effectively changes the
> functionality depending on the current type.
[snip]

What about implementing a copy-constructor for the Base and then have

class Derived_1 : public Base {

Derived_1 ( Base const & other )
: Base ( other )
{}

Derived_1 ( Derived_1 const & other )
: Base ( other )
{}

};

and similarly for Derived_2, ... ?

I think, if the copy-constructor for Base is implemented properly, the
compiler-generated copy-constructor for the derived classes would do the
same thing as the above, so you could even ditch that. Now, _that_ looks
very much like the code, I snipped. I clearly do not understand your
problem. Maybe, you need to post more details, because I lack the
imagination for:

> Furthermore the auto
> generated copy constructor is unusable. It has undefined behavior
> because of some special internal storage dependencies. It also has to do
> with multiple inheritance, so I could not move the code to a member
> function either.

If that is true, I do not see how the constructors _from_ the base can
possibly work correctly if they are just:

> Container1(const ContainerBase& r)
> : ContainerBase(r)
> {}



Best

Kai-Uwe Bux

Victor Bazarov

10/26/2008 1:56:00 AM

0

Juha Nieminen wrote:
> Marcel Müller wrote:
>> is there a way to avoid the automatic copy constructor generation.
>
> Yes: Implement your own copy constructor. That will make the compiler
> to not to create a default one.

You don't have to implement it. Just declare one. If your program does
not use it, you don't have to define it. And to make sure the program
does not use it, declare it 'private'.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Pete Becker

10/26/2008 11:04:00 AM

0

On 2008-10-25 21:55:54 -0400, Victor Bazarov <v.Abazarov@comAcast.net> said:

> Juha Nieminen wrote:
>> Marcel Müller wrote:
>>> is there a way to avoid the automatic copy constructor generation.
>>
>> Yes: Implement your own copy constructor. That will make the compiler
>> to not to create a default one.
>
> You don't have to implement it. Just declare one. If your program
> does not use it, you don't have to define it. And to make sure the
> program does not use it, declare it 'private'.
>

And a note for the future: with C++0X you don't need to declare it private.

class C
{
public:
C(const C&) = delete;
};

The "= delete" says that it doesn't exist. There's also "= default", to
tell the compiler to generate the default version even if it wouldn't
otherwise. These also apply to default constructors, generated
assignment operators, etc.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Marcel Müller

10/26/2008 12:36:00 PM

0

Hi,

Pete Becker schrieb:
> And a note for the future: with C++0X you don't need to declare it private.
>
> class C
> {
> public:
> C(const C&) = delete;
> };

thanks! This is the solution.

Unfortunately all my compilers are far away from C++0X, so I have to do
it the hard way so far.


Marcel

osmium

10/26/2008 2:53:00 PM

0

"Pete Becker" wrote:

>> You don't have to implement it. Just declare one. If your program does
>> not use it, you don't have to define it. And to make sure the program
>> does not use it, declare it 'private'.
>>
>
> And a note for the future: with C++0X you don't need to declare it
> private.
>
> class C
> {
> public:
> C(const C&) = delete;
> };
>
> The "= delete" says that it doesn't exist. There's also "= default", to
> tell the compiler to generate the default version even if it wouldn't
> otherwise. These also apply to default constructors, generated assignment
> operators, etc.

I might like that. That's the first exposure I have had to this new
language of which you speak. I think if it is going to take off, it needs a
better name. I thought, and still do, that C++ is a bad name. The God
awful moniker of this thing is even worse than C++ is.

It kind of reminds me of the Microsoft's annoying obsession to use
meaningless words such as "Explorer". I think the idea was that "Explorer"
is a better "Navigator". Maybe people would think that "Gamma" was a better
"C"?


Pete Becker

10/26/2008 3:55:00 PM

0

On 2008-10-26 10:53:05 -0400, "osmium" <r124c4u102@comcast.net> said:

>
> I might like that. That's the first exposure I have had to this new
> language of which you speak. I think if it is going to take off, it needs a
> better name. I thought, and still do, that C++ is a bad name. The God
> awful moniker of this thing is even worse than C++ is.
>

The name C++0x is used to refer to the upcoming standard. Once it
becomes a standard, the language it defines will be called C++.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Ian Collins

10/26/2008 9:38:00 PM

0

Pete Becker wrote:
> On 2008-10-25 21:55:54 -0400, Victor Bazarov <v.Abazarov@comAcast.net>
> said:
>
>> Juha Nieminen wrote:
>>> Marcel Müller wrote:
>>>> is there a way to avoid the automatic copy constructor generation.
>>>
>>> Yes: Implement your own copy constructor. That will make the compiler
>>> to not to create a default one.
>>
>> You don't have to implement it. Just declare one. If your program
>> does not use it, you don't have to define it. And to make sure the
>> program does not use it, declare it 'private'.
>>
>
> And a note for the future: with C++0X you don't need to declare it private.
>
> class C
> {
> public:
> C(const C&) = delete;
> };
>
> The "= delete" says that it doesn't exist. There's also "= default", to
> tell the compiler to generate the default version even if it wouldn't
> otherwise. These also apply to default constructors, generated
> assignment operators, etc.
>
I can see the benefit of "= default", but what benefits does "= delete"
offer over private constructors?

--
Ian Collins

Pete Becker

10/27/2008 1:05:00 AM

0

On 2008-10-26 17:37:53 -0400, Ian Collins <ian-news@hotmail.com> said:

> Pete Becker wrote:
>> On 2008-10-25 21:55:54 -0400, Victor Bazarov <v.Abazarov@comAcast.net>
>> said:
>>
>>> Juha Nieminen wrote:
>>>> Marcel Müller wrote:
>>>>> is there a way to avoid the automatic copy constructor generation.
>>>>
>>>> Yes: Implement your own copy constructor. That will make the compiler
>>>> to not to create a default one.
>>>
>>> You don't have to implement it. Just declare one. If your program
>>> does not use it, you don't have to define it. And to make sure the
>>> program does not use it, declare it 'private'.
>>>
>>
>> And a note for the future: with C++0X you don't need to declare it private.
>>
>> class C
>> {
>> public:
>> C(const C&) = delete;
>> };
>>
>> The "= delete" says that it doesn't exist. There's also "= default", to
>> tell the compiler to generate the default version even if it wouldn't
>> otherwise. These also apply to default constructors, generated
>> assignment operators, etc.
>>
> I can see the benefit of "= default", but what benefits does "= delete"
> offer over private constructors?

A bit of clarity. A private constructor can be implemented, and used by
members and friends. "= delete" says it doesn't exist.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Juha Nieminen

10/27/2008 6:16:00 PM

0

Pete Becker wrote:
> There's also "= default", to
> tell the compiler to generate the default version even if it wouldn't
> otherwise.

Will it be possible to call the compiler-generated copy constructor
from a user-defined copy constructor?