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 > Copy constructors
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Copy constructors

Réponse
 
LinkBack Outils de la discussion
Vieux 18/10/2007, 16h02   #1
keith@bytebrothers.co.uk
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Copy constructors


Hi, I've been through the FAQ-lite and can't see this mentioned, so
here goes...

I've got an abstract base class called Base which has no copy
constructor at all. In the derived class I have something like this:

// derived.h-----------------------------------------------------
class DerivedPrivate; // Not defined here
class Derived : public Base
{
private:
class DerivedPrivate* const p_;

public:
Derived();
Derived(const Derived& s);
// remainder snipped
}
// end--------------------------------------------------------------

// derived.cc----------------------------------------------------
// definition of DerivedPrivate skipped
Derived:erived() : p_(new DerivedPrivate()) {}

Derived:erived(const Derived& s) : p_(new DerivedPrivate())
{ *p_ = *(s.p_); }
// remainder skipped
// end--------------------------------------------------------------

Now this all compiles and works just fine, but when I turn on "-Wall -
W" in gcc, it tells me that:

derived.cc:134: warning: base class 'class Base' should be explicitly
initialized in the copy constructor

I'm afraid I'm being rather dense today, as I don't understand what
it's complaining about. Can someone explain for me please?

Thx!

  Réponse avec citation
Vieux 18/10/2007, 16h06   #2
Barry
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

keith@bytebrothers.co.uk wrote:
> Hi, I've been through the FAQ-lite and can't see this mentioned, so
> here goes...
>
> I've got an abstract base class called Base which has no copy
> constructor at all. In the derived class I have something like this:
>
> // derived.h-----------------------------------------------------
> class DerivedPrivate; // Not defined here
> class Derived : public Base
> {
> private:
> class DerivedPrivate* const p_;
>
> public:
> Derived();
> Derived(const Derived& s);
> // remainder snipped
> }
> // end--------------------------------------------------------------
>
> // derived.cc----------------------------------------------------
> // definition of DerivedPrivate skipped
> Derived:erived() : p_(new DerivedPrivate()) {}
>
> Derived:erived(const Derived& s) : p_(new DerivedPrivate())
> { *p_ = *(s.p_); }
> // remainder skipped
> // end--------------------------------------------------------------
>
> Now this all compiles and works just fine, but when I turn on "-Wall -
> W" in gcc, it tells me that:
>
> derived.cc:134: warning: base class 'class Base' should be explicitly
> initialized in the copy constructor
>
> I'm afraid I'm being rather dense today, as I don't understand what
> it's complaining about. Can someone explain for me please?
>


It complains that you should write your Derived ctor in this way:

Derived:erived()
: Base()
, p_(new DerivedPrivate())
{}


  Réponse avec citation
Vieux 18/10/2007, 16h25   #3
keith@bytebrothers.co.uk
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

On 18 Oct, 16:06, Barry <dhb2...@gmail.com> wrote:
> ke...@bytebrothers.co.uk wrote:
> > Now this all compiles and works just fine, but when I turn on "-Wall -
> > W" in gcc, it tells me that:

>
> > derived.cc:134: warning: base class 'class Base' should be explicitly
> > initialized in the copy constructor

>
> > I'm afraid I'm being rather dense today, as I don't understand what
> > it's complaining about. Can someone explain for me please?

>
> It complains that you should write your Derived ctor in this way:
>
> Derived:erived()
> : Base()
> , p_(new DerivedPrivate())
> {}


OK, this makes the warning go away - thanks. Now, what's happening?
I thought that by the time we reached Derived's constructor (in this
case, copy constructor), Base was guaranteed to have been fully
constructed. This result implies I am wrong...

  Réponse avec citation
Vieux 18/10/2007, 16h37   #4
Joe Greer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

keith@bytebrothers.co.uk wrote in news:1192721104.884316.307060
@k35g2000prh.googlegroups.com:

> On 18 Oct, 16:06, Barry <dhb2...@gmail.com> wrote:
>> ke...@bytebrothers.co.uk wrote:
>> > Now this all compiles and works just fine, but when I turn on "-Wall -
>> > W" in gcc, it tells me that:

>>
>> > derived.cc:134: warning: base class 'class Base' should be explicitly
>> > initialized in the copy constructor

>>
>> > I'm afraid I'm being rather dense today, as I don't understand what
>> > it's complaining about. Can someone explain for me please?

>>
>> It complains that you should write your Derived ctor in this way:
>>
>> Derived:erived()
>> : Base()
>> , p_(new DerivedPrivate())
>> {}

>
> OK, this makes the warning go away - thanks. Now, what's happening?
> I thought that by the time we reached Derived's constructor (in this
> case, copy constructor), Base was guaranteed to have been fully
> constructed. This result implies I am wrong...
>


Don't read too much into the syntax. This basically just tells the
compiler which constructor to use for the base class and provides the
opportunity to provide parameters to the base class' constructor. By the
time your Derived member initialization occurs and your constructor body is
executed, the base class will have been initialized.

joe
  Réponse avec citation
Vieux 18/10/2007, 16h49   #5
robin
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

On Oct 18, 11:25 pm, ke...@bytebrothers.co.uk wrote:
> On 18 Oct, 16:06, Barry <dhb2...@gmail.com> wrote:
>
>
>
>
>
> > ke...@bytebrothers.co.uk wrote:
> > > Now this all compiles and works just fine, but when I turn on "-Wall -
> > > W" in gcc, it tells me that:

>
> > > derived.cc:134: warning: base class 'class Base' should be explicitly
> > > initialized in the copy constructor

>
> > > I'm afraid I'm being rather dense today, as I don't understand what
> > > it's complaining about. Can someone explain for me please?

>
> > It complains that you should write your Derived ctor in this way:

>
> > Derived:erived()
> > : Base()
> > , p_(new DerivedPrivate())
> > {}

>
> OK, this makes the warning go away - thanks. Now, what's happening?
> I thought that by the time we reached Derived's constructor (in this
> case, copy constructor), Base was guaranteed to have been fully
> constructed. This result implies I am wrong...- Hide quoted text -
>
> - Show quoted text -


Hmmm... but we write such code:

class base
{
public:
base(int bn){}
~base(){}
};

class derived : public base
{
public:
derived(int dn) : base(dn){} // call base class constructor
~derived(){}
};

When it comes to the execution of derived(int dn){}, according to your
understanding, it is meaningless to call base() since base's been
constructed. But this really is what our code usually looks like.

I think by the time we reach Derived's constructor, it is just the
start to construct a Derived object, which is to say "we are going to
construct a Derived object now, and we should start from the
construction of its base".

Regards,
-robin

  Réponse avec citation
Vieux 18/10/2007, 16h57   #6
keith@bytebrothers.co.uk
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

On 18 Oct, 16:37, Joe Greer <jgr...@doubletake.com> wrote:
> ke...@bytebrothers.co.uk wrote in news:1192721104.884316.307060
> @k35g2000prh.googlegroups.com:
>
> > OK, this makes the warning go away - thanks. Now, what's happening?
> > I thought that by the time we reached Derived's constructor (in this
> > case, copy constructor), Base was guaranteed to have been fully
> > constructed. This result implies I am wrong...

>
> Don't read too much into the syntax. This basically just tells the
> compiler which constructor to use for the base class and provides the
> opportunity to provide parameters to the base class' constructor. By the
> time your Derived member initialization occurs and your constructor body is
> executed, the base class will have been initialized.


Ahhh... My understanding was _nearly_ correct; By the time we reach
Derived's constructor's BODY, Base is guaranteed to have been fully
constructed. But while we are still in the initialisation list, we
can (and apparently should) explicitly call Base's constructor.

Have I got it right now?!

  Réponse avec citation
Vieux 18/10/2007, 18h11   #7
Erik Wikström
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

On 2007-10-18 17:02, keith@bytebrothers.co.uk wrote:
> Hi, I've been through the FAQ-lite and can't see this mentioned, so
> here goes...
>
> I've got an abstract base class called Base which has no copy
> constructor at all. In the derived class I have something like this:
>
> // derived.h-----------------------------------------------------
> class DerivedPrivate; // Not defined here
> class Derived : public Base
> {
> private:
> class DerivedPrivate* const p_;
>
> public:
> Derived();
> Derived(const Derived& s);
> // remainder snipped
> }
> // end--------------------------------------------------------------
>
> // derived.cc----------------------------------------------------
> // definition of DerivedPrivate skipped
> Derived:erived() : p_(new DerivedPrivate()) {}
>
> Derived:erived(const Derived& s) : p_(new DerivedPrivate())
> { *p_ = *(s.p_); }


Just a question, does not DerivedPrivate have a copy-constructor? You
should be able to use something like

Derived:erived(const Derived& s)
: Base(),
p_(new DerivedPrivate(*(s.p))) // Instead of assignment in the body
{}

--
Erik Wikström
  Réponse avec citation
Vieux 18/10/2007, 18h34   #8
Bo Persson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

keith@bytebrothers.co.uk wrote:
:: Hi, I've been through the FAQ-lite and can't see this mentioned,
:: so here goes...
::
:: I've got an abstract base class called Base which has no copy
:: constructor at all. In the derived class I have something like
:: this:
::
:: // derived.h-----------------------------------------------------
:: class DerivedPrivate; // Not defined here
:: class Derived : public Base
:: {
:: private:
:: class DerivedPrivate* const p_;
::
:: public:
:: Derived();
:: Derived(const Derived& s);
:: // remainder snipped
:: }
:: //
:: end--------------------------------------------------------------
::
:: // derived.cc----------------------------------------------------
:: // definition of DerivedPrivate skipped
:: Derived:erived() : p_(new DerivedPrivate()) {}
::
:: Derived:erived(const Derived& s) : p_(new DerivedPrivate())
:: { *p_ = *(s.p_); }
:: // remainder skipped
:: //
:: end--------------------------------------------------------------
::
:: Now this all compiles and works just fine, but when I turn on
:: "-Wall - W" in gcc, it tells me that:
::
:: derived.cc:134: warning: base class 'class Base' should be
:: explicitly initialized in the copy constructor
::
:: I'm afraid I'm being rather dense today, as I don't understand what
:: it's complaining about. Can someone explain for me please?
::

It is just a warning that it is very unusual to have a copy
constructor that does not call the copy constructor of the base class.
You default construct the base and then copy the derived class.

More idiomatic would be:

Derived:erived(const Derived& s) : Base(s), p_(new
DerivedPrivate(*(s.p_)))
{ }


Bo Persson






  Réponse avec citation
Vieux 18/10/2007, 18h43   #9
Joe Greer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

keith@bytebrothers.co.uk wrote in
news:1192723042.495675.186110@e34g2000pro.googlegr oups.com:

> On 18 Oct, 16:37, Joe Greer <jgr...@doubletake.com> wrote:
>> ke...@bytebrothers.co.uk wrote in news:1192721104.884316.307060
>> @k35g2000prh.googlegroups.com:
>>
>> > OK, this makes the warning go away - thanks. Now, what's
>> > happening? I thought that by the time we reached Derived's
>> > constructor (in this case, copy constructor), Base was guaranteed
>> > to have been fully constructed. This result implies I am wrong...

>>
>> Don't read too much into the syntax. This basically just tells the
>> compiler which constructor to use for the base class and provides the
>> opportunity to provide parameters to the base class' constructor. By
>> the time your Derived member initialization occurs and your
>> constructor body is executed, the base class will have been
>> initialized.

>
> Ahhh... My understanding was _nearly_ correct; By the time we reach
> Derived's constructor's BODY, Base is guaranteed to have been fully
> constructed. But while we are still in the initialisation list, we
> can (and apparently should) explicitly call Base's constructor.
>
> Have I got it right now?!
>
>


You can picture it like that as long as you realize that the base class
(es) constructors will get called in the order they are declared in the
class and not in any arbitrary order, then the member initialization(s)
for your derived class will occur, and then the body of the constructor
will be invoked. Remember that you can have multiple inheritance, so
you may have more than one base class constructor to specify.

So, for example:

#include <iostream>
#include <string>

class Base {
int m_i;
public:
Base(int i) : m_i(i) {std::cout << "Base" << std::endl;}
};


class Base1 {
int m_i;
public:
Base1(int i) : m_i(i) {std::cout << "Base1" << std::endl;}
};

class Item1 {
public:
Item1() { std::cout << "Item1" << std::endl;}
};

class Item2 {
public:
Item2() { std::cout << "Item2" << std::endl;}
};

class Derived : public Base1, public Base {
Item1 m_Item1;
Item2 m_Item2;
public:
Derived(int i) : Base(i), Base1(i), m_Item2(), m_Item1() {std::cout
<< "Derived" << std::endl;}
};


int main()
{
Derived d(5);
}

The output of this program is:

Base1
Base
Item1
Item2
Derived

As you can see, the bases are initialized in the order declared in the
class definition, not in the order they appear in the constructor list
and the items are initialized in the order they appear in the class, not
in the order of the list, but all of the items in the list are done
before the body of the constructor is executed.



Hope that s,
joe
  Réponse avec citation
Vieux 18/10/2007, 18h59   #10
Pete Becker
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

On 2007-10-18 11:57:22 -0400, keith@bytebrothers.co.uk said:

>
> Ahhh... My understanding was _nearly_ correct; By the time we reach
> Derived's constructor's BODY, Base is guaranteed to have been fully
> constructed. But while we are still in the initialisation list, we
> can (and apparently should) explicitly call Base's constructor.
>
> Have I got it right now?!


Yes, except that you don't need to explicitly mention Base's
constructor if you want the default constructor. That's the one that
the compiler will use if you don't mention Base's constructor at all.
Busybody compilers might give you a warning for doing that, but the
behavior is well defined.

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

  Réponse avec citation
Vieux 19/10/2007, 09h03   #11
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Copy constructors

On Oct 18, 5:02 pm, ke...@bytebrothers.co.uk wrote:
> Hi, I've been through the FAQ-lite and can't see this mentioned, so
> here goes...


> I've got an abstract base class called Base which has no copy
> constructor at all.


No you don't. Every class has a copy constructor declared.
Always. The most you can do is to make it private, and not
provide an implementation.

> In the derived class I have something like this:


> // derived.h-----------------------------------------------------
> class DerivedPrivate; // Not defined here
> class Derived : public Base
> {
> private:
> class DerivedPrivate* const p_;


> public:
> Derived();
> Derived(const Derived& s);
> // remainder snipped}


> // end--------------------------------------------------------------
>
> // derived.cc----------------------------------------------------
> // definition of DerivedPrivate skipped
> Derived:erived() : p_(new DerivedPrivate()) {}


> Derived:erived(const Derived& s) : p_(new DerivedPrivate())
> { *p_ = *(s.p_); }
> // remainder skipped
> // end--------------------------------------------------------------


> Now this all compiles and works just fine, but when I turn on "-Wall -
> W" in gcc, it tells me that:


> derived.cc:134: warning: base class 'class Base' should be explicitly
> initialized in the copy constructor


> I'm afraid I'm being rather dense today, as I don't understand what
> it's complaining about. Can someone explain for me please?


The only explination I can see is that the author of this
warning message doesn't understand C++. You're Derived copy
constructor calls (and should call) the default constructor of
the Base class, which is probably what it should do (if e.g. the
Base class has no data members). At the very least, the warning
is only relevant if the Base class has data members.

--
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 22h53.


É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 ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,20258 seconds with 19 queries