Copy constructors

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • keith@bytebrothers.co.uk

    #1

    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::Derive d() : p_(new DerivedPrivate( )) {}

    Derived::Derive d(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!

  • Barry

    #2
    Re: Copy constructors

    keith@bytebroth ers.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::Derive d() : p_(new DerivedPrivate( )) {}
    >
    Derived::Derive d(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::Derive d()
    : Base()
    , p_(new DerivedPrivate( ))
    {}


    Comment

    • keith@bytebrothers.co.uk

      #3
      Re: Copy constructors

      On 18 Oct, 16:06, Barry <dhb2...@gmail. comwrote:
      ke...@bytebroth ers.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::Derive d()
      : 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...

      Comment

      • Joe Greer

        #4
        Re: Copy constructors

        keith@bytebroth ers.co.uk wrote in news:1192721104 .884316.307060
        @k35g2000prh.go oglegroups.com:
        On 18 Oct, 16:06, Barry <dhb2...@gmail. comwrote:
        >ke...@bytebrot hers.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::Deriv ed()
        > : 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

        Comment

        • robin

          #5
          Re: Copy constructors

          On Oct 18, 11:25 pm, ke...@bytebroth ers.co.uk wrote:
          On 18 Oct, 16:06, Barry <dhb2...@gmail. comwrote:
          >
          >
          >
          >
          >
          ke...@bytebroth ers.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::Derive d()
          : 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

          Comment

          • keith@bytebrothers.co.uk

            #6
            Re: Copy constructors

            On 18 Oct, 16:37, Joe Greer <jgr...@doublet ake.comwrote:
            ke...@bytebroth ers.co.uk wrote in news:1192721104 .884316.307060
            @k35g2000prh.go oglegroups.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?!

            Comment

            • =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=

              #7
              Re: Copy constructors

              On 2007-10-18 17:02, keith@bytebroth ers.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::Derive d() : p_(new DerivedPrivate( )) {}
              >
              Derived::Derive d(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::Derive d(const Derived& s)
              : Base(),
              p_(new DerivedPrivate( *(s.p))) // Instead of assignment in the body
              {}

              --
              Erik Wikström

              Comment

              • Bo Persson

                #8
                Re: Copy constructors

                keith@bytebroth ers.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::Derive d() : p_(new DerivedPrivate( )) {}
                ::
                :: Derived::Derive d(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::Derive d(const Derived& s) : Base(s), p_(new
                DerivedPrivate( *(s.p_)))
                { }


                Bo Persson






                Comment

                • Pete Becker

                  #9
                  Re: Copy constructors

                  On 2007-10-18 11:57:22 -0400, keith@bytebroth ers.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)

                  Comment

                  • James Kanze

                    #10
                    Re: Copy constructors

                    On Oct 18, 5:02 pm, ke...@bytebroth ers.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::Derive d() : p_(new DerivedPrivate( )) {}
                    Derived::Derive d(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.kan ze@gmail.com
                    Conseils en informatique orientée objet/
                    Beratung in objektorientier ter Datenverarbeitu ng
                    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                    Comment

                    Working...