multiple inheritance and constructors

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jimmy Johns

    multiple inheritance and constructors

    Hi, I have some classes as follows:

    #include <iostream>

    using namespace std;

    class A {
    public:
    virtual A* clone() const = 0;
    };
    class B {
    public:
    B(const B& rhs) : p(0)
    {
    delete p;
    p = new int;
    *p = *rhs.p;
    }
    private:
    int* p;
    };
    class C : public A, public B {
    public:
    C* clone() const
    {
    #24 return new C(*this);
    }
    };
    int main()
    {
    #29 A* pa = new C;
    A* pa2 = pa->clone();
    }

    this code gives the following errors under g++/cygwin:
    29: no matching function for call to C::C()
    24: candidates are C::C(const C&)

    okay... this is puzzling. If I take out B's copy constructor, then it
    compiles. It also appears that if I define any sort of new constructors
    (default, non-defualt ones), then I cannot use the compiler supplied
    defaults. The compiler then complains that it cannot find those default
    constructors. Is this just an issue with MI or in general? Also, are there
    any solutions to this besides defining all the constructors, copy
    constructors in the inheritance hierarchy? Thanks in advance.

    JJ.


  • John Harrison

    #2
    Re: multiple inheritance and constructors


    "Jimmy Johns" <asdf@asdf123as df.net> wrote in message
    news:bhnpg7$22i 5$1@news.eecs.u mich.edu...[color=blue]
    > Hi, I have some classes as follows:
    >
    > #include <iostream>
    >
    > using namespace std;
    >
    > class A {
    > public:
    > virtual A* clone() const = 0;
    > };
    > class B {
    > public:
    > B(const B& rhs) : p(0)
    > {
    > delete p;
    > p = new int;
    > *p = *rhs.p;
    > }
    > private:
    > int* p;
    > };
    > class C : public A, public B {
    > public:
    > C* clone() const
    > {
    > #24 return new C(*this);
    > }
    > };
    > int main()
    > {
    > #29 A* pa = new C;
    > A* pa2 = pa->clone();
    > }
    >
    > this code gives the following errors under g++/cygwin:
    > 29: no matching function for call to C::C()
    > 24: candidates are C::C(const C&)
    >
    > okay... this is puzzling. If I take out B's copy constructor, then it
    > compiles. It also appears that if I define any sort of new constructors
    > (default, non-defualt ones), then I cannot use the compiler supplied
    > defaults.[/color]

    If you define any ctor, then the compiler will not generate a default
    (no-arg) ctor. It will still generate a copy ctor.
    [color=blue]
    > The compiler then complains that it cannot find those default
    > constructors. Is this just an issue with MI or in general?[/color]

    In general.
    [color=blue]
    > Also, are there
    > any solutions to this besides defining all the constructors, copy
    > constructors in the inheritance hierarchy? Thanks in advance.
    >
    > JJ.
    >[/color]

    There is no issue, you seem to lack confidence in C++ and assume that it is
    going to force you do to lots of work.

    By defining a ctor, you lose the default ctor. That makes sense since a
    class with no ctors must still be constructed somehow, so the compiler
    generates a default ctor. As soon as you write a ctor, you are saying 'I
    know how to construct this class, don't generate a default ctor for me'.
    Which again is sensible, many classes don't want a default ctor.

    None of this has anything to do with copy ctors which are still generated by
    the compiler unless you write your own.

    john


    Comment

    • John Isaacks

      #3
      Re: multiple inheritance and constructors


      [color=blue]
      > okay... this is puzzling. If I take out B's copy constructor, then it
      > compiles. It also appears that if I define any sort of new constructors
      > (default, non-defualt ones), then I cannot use the compiler supplied
      > defaults. The compiler then complains that it cannot find those default
      > constructors. Is this just an issue with MI or in general? Also, are[/color]
      there[color=blue]
      > any solutions to this besides defining all the constructors, copy
      > constructors in the inheritance hierarchy? Thanks in advance.
      >
      > JJ.
      >[/color]

      The compiler supplied copy constructor is a binary copy, so the pointers
      within the "B" class point to the same data. Once you have defined one of
      the copy constructors you pretty much have to declare them all.

      // something like this
      C(const &c):B(c) { }
      // or maybe this...
      C(const &c):B::B(c) { }




      Comment

      • Jimmy Johns

        #4
        Re: multiple inheritance and constructors

        but can anyone duplicate the error I'm getting? Right now my project in VC7
        has pretty much the same layout, but slightly more complicated, and it still
        insists that I define the ctor, copy ctor myself. Is this a bug or
        something in the standard?

        thanks.

        JJ
        "John Harrison" <john_andronicu s@hotmail.com> wrote in message
        news:bho283$1br 91$1@ID-196037.news.uni-berlin.de...[color=blue]
        >
        > "John Isaacks" <jisaacks@bells outh.net> wrote in message
        > news:vYJ%a.4534 $mE5.3005@fe05. atl2.webusenet. com...[color=green]
        > >
        > >[color=darkred]
        > > > okay... this is puzzling. If I take out B's copy constructor, then it
        > > > compiles. It also appears that if I define any sort of new[/color][/color][/color]
        constructors[color=blue][color=green][color=darkred]
        > > > (default, non-defualt ones), then I cannot use the compiler supplied
        > > > defaults. The compiler then complains that it cannot find those[/color][/color][/color]
        default[color=blue][color=green][color=darkred]
        > > > constructors. Is this just an issue with MI or in general? Also, are[/color]
        > > there[color=darkred]
        > > > any solutions to this besides defining all the constructors, copy
        > > > constructors in the inheritance hierarchy? Thanks in advance.
        > > >
        > > > JJ.
        > > >[/color]
        > >
        > > The compiler supplied copy constructor is a binary copy,[/color]
        >
        > No it isn't, its a memberwise copy.
        >[color=green]
        > > so the pointers
        > > within the "B" class point to the same data.[/color]
        >
        > That's true.
        >[color=green]
        > > Once you have defined one of
        > > the copy constructors you pretty much have to declare them all.[/color]
        >
        > But that isn't. Once you have defined a copy constructor for one class you
        > do *not* have to define it for other classes that use that class. This is
        > the difference between a memberwise copy and a bitwise copy. The designers
        > of C++ would have been *extremely* stupid to have gone for a bitwise copy,
        > fortunately they didn't.
        >
        > I suggest you write a couple of classes for yourself to test this out.
        >
        > john
        >
        >
        >[/color]


        Comment

        • John Harrison

          #5
          Re: multiple inheritance and constructors


          "Jimmy Johns" <asdf@asdf123as df.net> wrote in message
          news:bhoqfp$2jp 0$1@news.eecs.u mich.edu...[color=blue]
          > but can anyone duplicate the error I'm getting? Right now my project in[/color]
          VC7[color=blue]
          > has pretty much the same layout, but slightly more complicated, and it[/color]
          still[color=blue]
          > insists that I define the ctor, copy ctor myself. Is this a bug or
          > something in the standard?
          >[/color]

          No, its not a bug. Think about, your class B does not have a (compiler
          generated) default ctor, that's because you defined a copy ctor for B.
          Therefore your class C which derives from B cannot have a default ctor
          either, because the compiler generated default ctor for C would have to call
          the default ctor for B (how could the compiler be smart enough to generate
          anything else?). But the default ctor for B doesn't exist and isn't
          generated, so the default ctor for C cannot be generated.

          So to fix the bug, either write a default ctor for B, this will allow the
          compiler to generate a default ctor for C, or write a default ctor for C
          which can call whatever ctor for B you like.

          john


          Comment

          Working...