Is it ok to inherit from vector?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Freddy Flares

    #1

    Is it ok to inherit from vector?

    Like this.

    /*************** *****/
    class Card {
    public:
    Card() : rank(0), suit(0) {}
    ...
    private:
    int rank;
    int suit;
    };

    class Cards : public vector<Card> {
    public:
    Cards();
    ...
    };
    /*************** *****/

    What about other STL types like string?

    Thanks.


  • lilburne

    #2
    Re: Is it ok to inherit from vector?

    Freddy Flares wrote:[color=blue]
    > Like this.
    >
    > /*************** *****/
    > class Card {
    > public:
    > Card() : rank(0), suit(0) {}
    > ...
    > private:
    > int rank;
    > int suit;
    > };
    >
    > class Cards : public vector<Card> {
    > public:
    > Cards();
    > ...
    > };
    > /*************** *****/
    >
    > What about other STL types like string?
    >[/color]

    I wouldn't others would - see thread and make your own mind up.


    Comment

    • Gianni Mariani

      #3
      Re: Is it ok to inherit from vector?

      Freddy Flares wrote:[color=blue]
      > Like this.
      >
      > /*************** *****/
      > class Card {
      > public:
      > Card() : rank(0), suit(0) {}
      > ...
      > private:
      > int rank;
      > int suit;
      > };
      >
      > class Cards : public vector<Card> {
      > public:
      > Cards();
      > ...
      > };
      > /*************** *****/
      >
      > What about other STL types like string?[/color]


      Yes sure - no problems as long as any vector created with "Cards" is
      destroyed from Cards's destructor.

      Apart from this, the rest you'll hear is religion.

      G

      Comment

      • John Brown

        #4
        Re: Is it ok to inherit from vector?

        > Yes sure - no problems as long as any vector created with "Cards" is[color=blue]
        > destroyed from Cards's destructor.
        >
        > Apart from this, the rest you'll hear is religion.[/color]

        I agree. People like to quote ad nauseam about the lack of "virtual
        destructors" and "concrete" classes (including Stroustrup himself) but it's
        bunk no matter what the purists say (and with 20 years in the field I know
        what I'm talking about). If done properly it's not a problem.


        Comment

        • Cy Edmunds

          #5
          Re: Is it ok to inherit from vector?

          "Freddy Flares" <a@b.com> wrote in message
          news:boueij$ev9 $1@sparta.btint ernet.com...[color=blue]
          > Like this.
          >
          > /*************** *****/
          > class Card {
          > public:
          > Card() : rank(0), suit(0) {}
          > ...
          > private:
          > int rank;
          > int suit;
          > };
          >
          > class Cards : public vector<Card> {
          > public:
          > Cards();
          > ...
          > };
          > /*************** *****/
          >
          > What about other STL types like string?
          >
          > Thanks.
          >
          >[/color]

          I don't think it's a good idea. Standard containers aren't really designed
          to be base classes. I think generally that encapulation is a better paradigm
          than inheritance unless you are designing a set of polymorphic classes. The
          attractive thing about using inheritance with concrete types is that it can
          save you a little typing. But encapsulation is more flexible and
          maintainable IMHO.

          Of course encapsulation and inheritance can both be a waste of time if your
          only purpose is to add some functions. Just use functions! e.g.

          typedef std::vector<Car d> Deck;

          void shuffle(Deck &);
          Card deal(Deck &);
          const Card& peek(const Deck &);

          etc. This is actually a very clean design approach in a lot of cases.

          --
          Cy
          http://home.rochester.rr.com/cyhome/


          Comment

          • Bronek Kozicki

            #6
            Re: Is it ok to inherit from vector?

            On Wed, 12 Nov 2003 23:09:07 +0000 (UTC), Freddy Flares wrote:
            [color=blue]
            > class Cards : public vector<Card> {[/color]
            [color=blue]
            > What about other STL types like string?[/color]

            it's legal, but it's also dangerous, which means bad design. You'd
            rather use encapsulation or free functions accepting (vector<Card>&)
            parameter. Or if you really want to use inheritance, try this:

            class Cards : protected vector<Card>{
            using vector<Card>::s ize; // etc.



            B.

            Comment

            • tom_usenet

              #7
              Re: Is it ok to inherit from vector?

              On Thu, 13 Nov 2003 01:25:42 GMT, "John Brown" <_nospam@_nospa m.com>
              wrote:
              [color=blue][color=green]
              >> Yes sure - no problems as long as any vector created with "Cards" is
              >> destroyed from Cards's destructor.
              >>
              >> Apart from this, the rest you'll hear is religion.[/color]
              >
              >I agree. People like to quote ad nauseam about the lack of "virtual
              >destructors" and "concrete" classes (including Stroustrup himself) but it's
              >bunk no matter what the purists say (and with 20 years in the field I know
              >what I'm talking about). If done properly it's not a problem.[/color]

              I disagree. I agree that the virtual destructor problem is a minor
              thing. However, a much more major thing is the fact that Cards
              probably has class invariants that vector<Cards> doesn't. For a start
              there should perhaps be a separate Pack class and Hand class. Exposing
              the whole vector interface may cause difficult to track down bugs in
              the future, unless the Cards class is only used internally.

              Deriving from a container is generally a "quick hack" that you end up
              having to refactor in the long run anyway.

              Tom

              Comment

              • John Brown

                #8
                Re: Is it ok to inherit from vector?

                > I disagree. I agree that the virtual destructor problem is a minor[color=blue]
                > thing. However, a much more major thing is the fact that Cards
                > probably has class invariants that vector<Cards> doesn't. For a start
                > there should perhaps be a separate Pack class and Hand class. Exposing
                > the whole vector interface may cause difficult to track down bugs in
                > the future, unless the Cards class is only used internally.[/color]

                Actually I agree with you. A restricted interface is typically necessary
                though you can employ "using" statements to privatize public base class
                members if you want (unbeknownst to many developers though it's an ugly
                approach IMO). My real beef lies with those pedantic arguments that state
                you absolutely must not do it:

                a) Because of the virtual destructor issue
                b) Because it's a "concrete" class not intended for further derivation

                Well item a isn't an issue if properly controlled and item b is just a
                pie-in-the-sky philosophy. Why should someone write a regular (non-member)
                "toupper()" function for instance when it's cleaner to derive "MyString"
                from "std::strin g" and implement a member function that does this instead.
                It fits naturally into the OOP model and is therefore much cleaner
                (especially for strings and vectors which are a staple of most projects).
                Therefore, for a generic "vector" class it's ok to derive from it in many
                circumstances (to add additional functionality in a controlled environment
                for instance). When you need a restricted interface then you can consider
                encapsulation.


                Comment

                • Cy Edmunds

                  #9
                  Re: Is it ok to inherit from vector?

                  "John Brown" <_nospam@_nospa m.com> wrote in message
                  news:RTrtb.2406 $j1d.1681@news0 4.bloor.is.net. cable.rogers.co m...[color=blue][color=green]
                  > > I disagree. I agree that the virtual destructor problem is a minor
                  > > thing. However, a much more major thing is the fact that Cards
                  > > probably has class invariants that vector<Cards> doesn't. For a start
                  > > there should perhaps be a separate Pack class and Hand class. Exposing
                  > > the whole vector interface may cause difficult to track down bugs in
                  > > the future, unless the Cards class is only used internally.[/color]
                  >
                  > Actually I agree with you. A restricted interface is typically necessary
                  > though you can employ "using" statements to privatize public base class
                  > members if you want (unbeknownst to many developers though it's an ugly
                  > approach IMO). My real beef lies with those pedantic arguments that state
                  > you absolutely must not do it:
                  >
                  > a) Because of the virtual destructor issue
                  > b) Because it's a "concrete" class not intended for further derivation
                  >
                  > Well item a isn't an issue if properly controlled and item b is just a
                  > pie-in-the-sky philosophy. Why should someone write a regular (non-member)
                  > "toupper()" function for instance when it's cleaner to derive "MyString"
                  > from "std::strin g" and implement a member function that does this instead.[/color]

                  Great. Now you have two versions of std::string floating around which differ
                  only in that one has a new member function. If I want to use your toupper
                  function but only have a std::string available I have to convert to a
                  different class just to use it. If I *don't* want to use your toupper
                  function I can't just ignore it -- for instance when somebody passes me a
                  MyString I have to look up what it is. And what if I wan't to add a second
                  function? Should I make a third string class? You have neatly outlined why
                  you should never do what you are advising.
                  [color=blue]
                  > It fits naturally into the OOP model and is therefore much cleaner[/color]

                  <groan> If this is your idea of cleanliness I hope you don't cook.
                  [color=blue]
                  > (especially for strings and vectors which are a staple of most projects).
                  > Therefore, for a generic "vector" class it's ok to derive from it in many
                  > circumstances (to add additional functionality in a controlled environment
                  > for instance). When you need a restricted interface then you can consider
                  > encapsulation.
                  >
                  >[/color]

                  I agree that some writers get carried away with pedantic arguments about
                  concrete base classes, but I think the rest of your argument is nonsense.

                  --
                  Cy
                  http://home.rochester.rr.com/cyhome/


                  Comment

                  • Bronek Kozicki

                    #10
                    Re: Is it ok to inherit from vector?

                    On Sat, 15 Nov 2003 15:46:57 GMT, John Brown wrote:[color=blue]
                    > It fits naturally into the OOP model and is therefore much cleaner
                    > (especially for strings and vectors which are a staple of most projects).
                    > Therefore, for a generic "vector" class it's ok to derive from it in many[/color]

                    what you advise here is just against OOP. It is called
                    "strong coupling" and "mixing interface with implementation" .


                    B.

                    Comment

                    • lilburne

                      #11
                      Re: Is it ok to inherit from vector?

                      John Brown wrote:
                      [color=blue][color=green]
                      >>Yes sure - no problems as long as any vector created with "Cards" is
                      >>destroyed from Cards's destructor.
                      >>
                      >>Apart from this, the rest you'll hear is religion.[/color]
                      >
                      >
                      > I agree. People like to quote ad nauseam about the lack of "virtual
                      > destructors" and "concrete" classes (including Stroustrup himself) but it's
                      > bunk no matter what the purists say (and with 20 years in the field I know
                      > what I'm talking about). If done properly it's not a problem.
                      >[/color]

                      You have to be sure that nobody ever decides to delete your
                      derived class via a base class pointer. As time goes on the
                      likelihood is that someone will, then you have undefined
                      behaviour.

                      Here is an example that results in segmentation error in
                      addition to the memory leak, if you uncomment the int b in A.

                      #include <vector>

                      class A {
                      int a;
                      // int b;
                      public:
                      virtual ~A() {};

                      };

                      class B : public std::vector<int > {
                      public:
                      virtual ~B() {};
                      };

                      class C: public A , public B {
                      public:
                      };

                      C* f()
                      {
                      new C;
                      }


                      int main()
                      {
                      std::vector<int >* b = f();
                      delete b;
                      return 0;
                      }

                      Comment

                      Working...