Inheriting from std::vector?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pete Becker

    #16
    Re: Inheriting from std::vector?

    lilburne wrote:[color=blue]
    >
    > Pete Becker wrote:
    >[color=green]
    > > lilburne wrote:
    > >[color=darkred]
    > >>>You take it wrong. Pay attention to context.
    > >>>
    > >>
    > >>Amazing:
    > >>[/color]
    > >
    > >
    > > You wrote bad code, having been told it's bad. What's your point?
    > >[/color]
    >
    > What was bad about it?[/color]

    PLONK.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)

    Comment

    • lilburne

      #17
      Re: Inheriting from std::vector?

      Pete Becker wrote:
      [color=blue]
      > lilburne wrote:
      >[color=green]
      >>Pete Becker wrote:
      >>
      >>[color=darkred]
      >>>lilburne wrote:
      >>>
      >>>
      >>>>>You take it wrong. Pay attention to context.
      >>>>>
      >>>>
      >>>>Amazing:
      >>>>
      >>>
      >>>
      >>>You wrote bad code, having been told it's bad. What's your point?
      >>>[/color]
      >>
      >>What was bad about it?[/color]
      >
      >
      > PLONK.
      >[/color]

      Tsk! You jump in to sanction using a class inheritance
      design, that not only restricts how the heirarchy may be
      used, but which also has the potential to cause resource
      leakage, and then become all sniffy.

      Its no good simply saying 'don't do it', because it will be
      done. If you took 10 'C++' programmers at random and asked
      "What does the following program print?" you'd be lucky to
      get the correct answer from 4 of them. Ask the 4 that got it
      right the same question again having removed virtual from
      A's destructor and you might get 2 left.

      class A {
      public:
      virtual void func1() { cout << "a::func1" << endl; }
      void func2() { cout << "a::func2" << endl; }
      virtual void func3() { cout << "a::func3" << endl; }
      virtual ~A() { cout << "a::~a" << endl; }
      };

      class B {
      public:
      virtual void func1() { cout << "b::func1" << endl; }
      void func2() { cout << "b::func2" << endl; }
      void func3() { cout << "b::func3" << endl; }
      virtual ~B() { cout << "b::~b" << endl; }
      };

      int main()
      {
      B* b = new B;
      A* a = b;
      a->func1();
      a->func2();
      a->func3();

      b->func1();
      b->func2();
      b->func3();

      delete a;
      return 0;
      }

      Its astonishing how many programmers do not understand the
      import of the keyword virtual. But you know that.

      Comment

      • Alf P. Steinbach

        #18
        Re: Inheriting from std::vector?

        On Fri, 24 Oct 2003 21:58:53 +0100, lilburne <lilburne@godzi lla.net> wrote:
        [color=blue]
        >Pete Becker wrote:
        >[color=green]
        >> lilburne wrote:
        >>[color=darkred]
        >>>>You take it wrong. Pay attention to context.
        >>>>
        >>>
        >>>Amazing:
        >>>[/color]
        >>
        >>
        >> You wrote bad code, having been told it's bad. What's your point?
        >>[/color]
        >
        >What was bad about it?[/color]

        You're destroying a non-polymorphic class object polymorphically (through a
        pointer to the base class object).

        But you knew that.

        It's illogical to ban usage of a feature just because that feature _can_
        be abused, since almost all language features _can_ be abused, and I think
        your use of such an illogical argument was the reason why Pete plonked you.

        Comment

        • lilburne

          #19
          Re: Inheriting from std::vector?

          Alf P. Steinbach wrote:
          [color=blue]
          > On Fri, 24 Oct 2003 21:58:53 +0100, lilburne <lilburne@godzi lla.net> wrote:
          >
          >[color=green]
          >>Pete Becker wrote:
          >>
          >>[color=darkred]
          >>>lilburne wrote:
          >>>
          >>>
          >>>>>You take it wrong. Pay attention to context.
          >>>>>
          >>>>
          >>>>Amazing:
          >>>>
          >>>
          >>>
          >>>You wrote bad code, having been told it's bad. What's your point?
          >>>[/color]
          >>
          >>What was bad about it?[/color]
          >
          >
          > You're destroying a non-polymorphic class object polymorphically (through a
          > pointer to the base class object).
          >
          > But you knew that.
          >
          > It's illogical to ban usage of a feature just because that feature _can_
          > be abused, since almost all language features _can_ be abused, and I think
          > your use of such an illogical argument was the reason why Pete plonked you.
          >[/color]

          It is unlikely that Pete Becker would derive a class from
          a base that has a non-virtual destructure, without some
          overriding reason to do so. Because he knows it is a
          resource leak waiting to happen, and that safer alternatives
          are usually available.

          To pretend that you can ensure that the polymorphic deletion
          on such a class heirarchy can be avoid just by saying "Don't
          do it" is ridiculous. The OP not only has an inheritance
          tree of depth four, but is also inheriting from a class that
          already exists. As there are already functions in the system
          that process the base class polymorphism is going to occur.

          Certain language features ought to be used with caution, IMO
          one should learn how to use them properly before you start
          to abuse them.

          Comment

          • Alf P. Steinbach

            #20
            Re: Inheriting from std::vector?

            On Sat, 25 Oct 2003 02:55:25 +0100, lilburne <lilburne@godzi lla.net> wrote:
            [color=blue]
            >Certain language features ought to be used with caution, IMO
            >one should learn how to use them properly before you start
            >to abuse them.[/color]

            Well, modest that I am I find it unlikely that either Pete or I don't
            know how to use inheritance properly, and I find it unlikely that either
            of us would abuse the mechanism.

            Perhaps you're referring to the OP?

            But the OP didn't code inheritance from std::vector; he's, er, inherited
            that code...

            Perhaps, then, you're referring to your own abusive example code?

            Comment

            • Rolf Magnus

              #21
              Re: Inheriting from std::vector?

              lilburne wrote:
              [color=blue][color=green][color=darkred]
              >>>>You wrote bad code, having been told it's bad. What's your point?
              >>>>
              >>>
              >>>What was bad about it?[/color]
              >>
              >>
              >> You're destroying a non-polymorphic class object polymorphically
              >> (through a pointer to the base class object).
              >>
              >> But you knew that.
              >>
              >> It's illogical to ban usage of a feature just because that feature
              >> _can_ be abused, since almost all language features _can_ be abused,
              >> and I think your use of such an illogical argument was the reason why
              >> Pete plonked you.
              >>[/color]
              >
              > It is unlikely that Pete Becker would derive a class from
              > a base that has a non-virtual destructure, without some
              > overriding reason to do so. Because he knows it is a
              > resource leak waiting to happen,[/color]

              No, it's not. Polymorphically destroying an object of that class is.
              A knife can be a useful tool, and it isn't evil. Hoever, using it to
              stab people is. Almost everything can be destructive if you want it to
              be.
              [color=blue]
              > and that safer alternatives are usually available.
              >
              > To pretend that you can ensure that the polymorphic deletion
              > on such a class heirarchy can be avoid just by saying "Don't
              > do it" is ridiculous.[/color]

              You could also reinterpret_cas t the pointer to char* and delete that
              one. It will also result in improper deletion. But why would anyone do
              such a stupid thing?
              [color=blue]
              > Certain language features ought to be used with caution, IMO
              > one should learn how to use them properly before you start
              > to abuse them.[/color]

              Nope. One should learn how to use them and never abuse them at all.

              Comment

              • lilburne

                #22
                Re: Inheriting from std::vector?

                Alf P. Steinbach wrote:[color=blue]
                > On Sat, 25 Oct 2003 02:55:25 +0100, lilburne <lilburne@godzi lla.net> wrote:
                >
                >[color=green]
                >>Certain language features ought to be used with caution, IMO
                >>one should learn how to use them properly before you start
                >>to abuse them.[/color]
                >
                >
                > Well, modest that I am I find it unlikely that either Pete or I don't
                > know how to use inheritance properly, and I find it unlikely that either
                > of us would abuse the mechanism.[/color]


                Then why sanction it for others?

                [color=blue]
                > Perhaps you're referring to the OP?
                >
                > But the OP didn't code inheritance from std::vector; he's, er, inherited
                > that code...[/color]

                The OP was proposing deriving 3 additional class from it. If
                he can't repair the initial inheritance scheme he can at
                least not inherit it, or perhaps reduce the potential risk
                by giving the initial inheriting class a virtual destructor.
                [color=blue]
                > Perhaps, then, you're referring to your own abusive example code?
                >[/color]

                The code presented isn't abusive. It simply demonstrated the
                problem you are likely to have when you have an inheritance
                tree whose base consists of a non virtual destructor. It
                could even exist in legacy code, which the deriver is
                unaware of, and whose original coder certainly wasn't
                abusing the language.

                Comment

                • lilburne

                  #23
                  Re: Inheriting from std::vector?

                  Rolf Magnus wrote:
                  [color=blue]
                  > lilburne wrote:
                  >
                  >[color=green][color=darkred]
                  >>>>>You wrote bad code, having been told it's bad. What's your point?
                  >>>>>
                  >>>>
                  >>>>What was bad about it?
                  >>>
                  >>>
                  >>>You're destroying a non-polymorphic class object polymorphically
                  >>>(through a pointer to the base class object).
                  >>>
                  >>>But you knew that.
                  >>>
                  >>>It's illogical to ban usage of a feature just because that feature
                  >>>_can_ be abused, since almost all language features _can_ be abused,
                  >>>and I think your use of such an illogical argument was the reason why
                  >>>Pete plonked you.
                  >>>[/color]
                  >>
                  >>It is unlikely that Pete Becker would derive a class from
                  >>a base that has a non-virtual destructure, without some
                  >>overriding reason to do so. Because he knows it is a
                  >>resource leak waiting to happen,[/color]
                  >
                  >
                  > No, it's not. Polymorphically destroying an object of that class is.
                  > A knife can be a useful tool, and it isn't evil. Hoever, using it to
                  > stab people is. Almost everything can be destructive if you want it to
                  > be.
                  >[/color]

                  As day follows night someone will delete an object of the
                  class polymorphically , there may already be doing so. There
                  might be code in the system that deletes pointers of the
                  base class. They may not, nor should they, even know that
                  the base pointer they are dealing with is of a derived class.

                  In any case by inheriting from the base you are implicitly
                  restricting the problem space that your class can be validly
                  used in, and you have passed a charged on to maintainence
                  due to a lazy implementation. All future users of the class
                  have to remember not to destroy via the base, or to call any
                  method that might do. But you could have avoid the cost by
                  using composition rather than inheritance.

                  Comment

                  • Alexander Terekhov

                    #24
                    Re: Inheriting from std::vector?


                    lilburne wrote:
                    [...][color=blue]
                    > In any case by inheriting from the base you are implicitly
                    > restricting the problem space that your class can be validly
                    > used in, and you have passed a charged on to maintainence
                    > due to a lazy implementation. All future users of the class
                    > have to remember not to destroy via the base, or to call any
                    > method that might do. But you could have avoid the cost by
                    > using composition rather than inheritance.[/color]

                    No thankyou.


                    (Subject: Re: blocking inheritance)

                    regards,
                    alexander.

                    Comment

                    • Simon Elliott

                      #25
                      Re: Inheriting from std::vector?

                      Pete Becker <petebecker@acm .org> writes[color=blue][color=green][color=darkred]
                      >> >>However, as std::vector doesn't have a virtual destructor it
                      >> >>shouldn't really be being used as a base class.
                      >> >
                      >> >
                      >> > There is no problem with using it as a base class as long as you don't
                      >> > destroy the object through a pointer to std::vector.
                      >> >[/color]
                      >>
                      >> And you ensure that how?[/color]
                      >
                      >You don't do it.[/color]

                      I would have thought that would be quite difficult.

                      If you work as part of a team of developers, or for a large company
                      where one team expects to reuse code from another team, you'd have to
                      carefully document the class. Even if your fellow developers remember to
                      trace the chain of inheritance right back to the base class and check,
                      how many of them will know that std::vector doesn't have a virtual
                      destructor? (I didn't know until I read this thread.)

                      If you're a one man band, you still might post some of your code on the
                      internet, sell it to somebody, or be very busy and need to subcontract a
                      project.

                      Even if you know (somehow) that you will never do the above, you might
                      need to do a rush job and think: "OK, I can inherit from my XYZ class,
                      job done and dusted." Then you find yourself in the debugger at three in
                      the morning, drinking jolt cola or black coffee.

                      All the same, there are times when I would like to be able to inherit
                      from a std::vector or other container. I tend to typedef my STL
                      container declarations:

                      typedef std::vector<int > CsectorList;

                      But then I find that I can't forward declare them, because you can't
                      forward declare a typedef. If I could safely do:

                      class CsectorList:pub lic std::vector<int >{};

                      Then I could forward declare this as:

                      class CsectorList;

                      Anyone got any ideas for safely achieving this?
                      --
                      Simon Elliott







                      Comment

                      • lilburne

                        #26
                        Re: Inheriting from std::vector?

                        Simon Elliott wrote:[color=blue]
                        > Pete Becker <petebecker@acm .org> writes
                        >[color=green][color=darkred]
                        >>>>>However, as std::vector doesn't have a virtual destructor it
                        >>>>>shouldn' t really be being used as a base class.
                        >>>>
                        >>>>
                        >>>>There is no problem with using it as a base class as long as you don't
                        >>>>destroy the object through a pointer to std::vector.
                        >>>>
                        >>>
                        >>>And you ensure that how?[/color]
                        >>
                        >>You don't do it.[/color]
                        >
                        >
                        > I would have thought that would be quite difficult.
                        >[/color]

                        You know, I know it, ...
                        [color=blue]
                        >
                        > All the same, there are times when I would like to be able to inherit
                        > from a std::vector or other container. I tend to typedef my STL
                        > container declarations:
                        >
                        > typedef std::vector<int > CsectorList;
                        >
                        > But then I find that I can't forward declare them, because you can't
                        > forward declare a typedef. If I could safely do:
                        >
                        > class CsectorList:pub lic std::vector<int >{};
                        >
                        > Then I could forward declare this as:
                        >
                        > class CsectorList;
                        >
                        > Anyone got any ideas for safely achieving this?[/color]

                        The question I'd ask is why you want to typedef the thing,
                        other than to avoid adding #include <vector>. I suppose it
                        might make it easier to turn it into a std::list, or
                        whatever, at some later stage. The problem is that you
                        haven't really hidden the fact that its a vector and haven't
                        stopped clients from using vector specific operations. I've
                        been there.

                        Another motivation I've seen is when someone inherits a
                        container and adds application specific operations to the
                        new class. The problem with this is that clients can still
                        treat it as a bare std::container circumventing any
                        application specific invariants you might want to impose.
                        IOW you don't protect access to the container.

                        Personally I'd either seperate the container specific
                        element from the application specific operations, or use the
                        has-a relationship between the classes. I prefer the later.
                        The result is I believe more robust over time.

                        Comment

                        • Simon Elliott

                          #27
                          Re: Inheriting from std::vector?

                          lilburne <lilburne@godzi lla.net> writes[color=blue]
                          >The question I'd ask is why you want to typedef the thing,
                          >other than to avoid adding #include <vector>. I suppose it
                          >might make it easier to turn it into a std::list, or
                          >whatever, at some later stage.[/color]

                          There's the clarity issue as well. This is discussed quite well here:



                          But I'm fairly sure that you still have to #include <vector>. More
                          unpleasantly, if your container is a
                          std::vector<lar ge_nontrivial_c lass>

                          you also need to #include "large_nontrivi al_class.h"

                          So classes which didn't need to know about either std::vector or
                          large_nontrivia l_class still need both includes.

                          If we were to inherit from std::container< large_nontrivia l_class>, the
                          inherited class could be forward declared and neither of these includes
                          would be necessary.
                          [color=blue]
                          >The problem is that you
                          >haven't really hidden the fact that its a vector and haven't
                          >stopped clients from using vector specific operations. I've
                          >been there.
                          >
                          >Another motivation I've seen is when someone inherits a
                          >container and adds application specific operations to the
                          >new class. The problem with this is that clients can still
                          >treat it as a bare std::container circumventing any
                          >application specific invariants you might want to impose.
                          >IOW you don't protect access to the container.[/color]

                          You could always inherit from it privately, but see below.
                          [color=blue]
                          >Personally I'd either seperate the container specific
                          >element from the application specific operations, or use the
                          >has-a relationship between the classes. I prefer the later.
                          >The result is I believe more robust over time.[/color]

                          Yes, and this would also be safer if the container had not got a virtual
                          destructor. On the other hand, there may be some usefulness in exposing
                          the underlying container, as this allows users to apply all the generic
                          algorithms from the standard library to your class.
                          --
                          Simon Elliott







                          Comment

                          Working...