why virtual base dtor gets called?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Peter Julian

    #16
    Re: why virtual base dtor gets called?


    "Howard" <alicebt@hotmai l.com> wrote in message
    news:ZHire.9476 05$w62.229941@b gtnsc05-news.ops.worldn et.att.net...[color=blue]
    >
    > "Peter Julian" <p_julian@trap. trap.com> wrote in message
    > news:Rfire.1619 $Qr3.338078@new s20.bellglobal. com...[color=green]
    > >
    > > "tuvok" <520001085531-0001@t-online.de> wrote in message
    > > news:d8jaa5$48a $03$1@news.t-online.com...[color=darkred]
    > >> "Peter Julian" wrote
    > >> >
    > >> > "tuvok" wrote in message
    > >> >
    > >> > > Is it correct that the virtual dtor of base gets called implicitly?
    > >> >
    > >> > Not really, the virtual d~tor of base class is invoked, not called.
    > >> >
    > >> > > Here's some code to demonstrate what I mean:
    > >> > > Class B has a virtual destructor, so has class D which
    > >> > > is derived from B. Deleting D calls the dtor of D and
    > >> > > then the dtor of B.
    > >> >
    > >> > B's d~tor is invoked and processed before D's d~tor can complete.
    > >> >
    > >> > > I was thinking that this would be true only for non-virtual dtor
    > >> > > case,
    > >> > > but I wouldn't have expected it happen for a virtual dtor.
    > >> > > For a class with a virtual dtor I would have expected that only
    > >> > > the dtor of D would be called when D gets deleted.
    > >> >
    > >> > You are describing a non-virtual d~tor. Only D's d~tor would be[/color][/color][/color]
    invoke.[color=blue][color=green][color=darkred]
    > >>
    > >> No, it's not the case. Both ~D and ~B are invoked no matter whether
    > >> the dtors are virtual or not. So there seems no difference whether
    > >> the dtors are virtual or not. Ie. always the dtors of all parts get[/color]
    > > invoked.[color=darkred]
    > >>[/color]
    > >
    > > In the case where a pointer isn't involved, the base's d~tor will still[/color][/color]
    be[color=blue][color=green]
    > > invoked but you'll have the warning. You said "when D gets deleted". In
    > > the
    > > case you had a pointer, something i didn't include in my example, your
    > > base
    > > c~tor would not have been invoked.
    > >[/color]
    >
    > Eh? Of course the base class destructor is invoked! Whenever a derived
    > class is destroyed, the destructors for any base classes *must* be[/color]
    invoked,[color=blue]
    > whether you're using pointers or automatic variables. Otherwise, the[/color]
    memory[color=blue]
    > allocated for the base class portion(s) of the object would never get
    > returned to the system.
    >
    > This is even true if the derived class object was assigned to a base class
    > pointer variable. The only difference in that case is that the base class
    > destructor needs to be virtual, or else the *derived* class destructor[/color]
    will[color=blue]
    > not get invoked.
    >
    > There is no way for the destruction of the derived class to *not* also
    > invoke the destructor of the base class (aside from invoking undefined
    > behavior or abnormally terminating the process).
    >
    > -Howard
    >[/color]

    I meant a Base * to a new D. My mistake. Its been a long day.

    Comment

    • Jim Langston

      #17
      Re: why virtual base dtor gets called?


      "Ron Natalie" <ron@spamcop.ne t> wrote in message
      news:42adf95a$0 $26294$9a6e19ea @news.newshosti ng.com...[color=blue]
      > tuvok wrote:[color=green]
      >> Is it correct that the virtual dtor of base gets called implicitly?[/color]
      >
      > Yes. Let me reiterate to make sure you understand.
      >
      > When an object is created, at the level of the most
      > derived object all the virtual bases are constructed
      > (in a depth first, left to right fashion). Then the
      > direct bases of the classes are constructed (in the
      > order listed in the class definition, not the mem-initializer
      > list), and then each non-static data member is constructed.
      > Then the constructor body of the object is run.
      >
      > Each subobject above recursively constructs it's subobjects
      > (with the exception of avoiding duplicate construction of
      > the virtual bases).
      >
      > There is nothing the program can do to change that ordering
      > (within defined behavior).
      >
      >
      > Objects are destructed in precisely the REVERSE ORDERING.
      >
      > Virtualness of the destructor, arguments to the constructor,
      > etc... have no bearing on this behavior. It always happens
      > in the same topological order described above.[/color]

      I just wrote a program and compiled and ran to test this theory, and it
      seems
      that "Objects are destructed in precisely the REVERSE ORDERING" is
      not always true. Here is the program:

      #include <iostream>

      class base
      {
      public:
      int i;
      base() { std::cout << "b ctor" << std::endl; }
      ~base() { std::cout << "b dtor" << std::endl; }
      };

      class derived : public base
      {
      public:
      derived() { std::cout << "d ctor" << std::endl; }
      ~derived() { std::cout << "d dtor" << std::endl; }
      };

      int _tmain(int argc, _TCHAR* argv[])
      {
      base* b;
      derived* d;

      b = new derived;
      delete b;

      std::cout << std::endl;

      d = new derived;
      delete d;

      char c;
      std::cin >> c;

      return 0;

      }

      And it's Output:

      b ctor
      d ctor
      b dtor

      b ctor
      d ctor
      d dtor
      b dtor

      As you can see, the derived dtor was NOT called when the derived was
      instatized to a base pointer.

      Change the base dtor to:

      produces this output:
      b ctor
      d ctor
      d dtor
      b dtor

      b ctor
      d ctor
      d dtor
      b dtor

      Where the derived dtor is called in both instances.

      But, yes, the base dtor does get called in either case either.


      Comment

      • Jim Langston

        #18
        Re: why virtual base dtor gets called?

        "Jim Langston" <tazmaster@rock etmail.com> wrote in message
        news:4%%re.820$ mD6.490@fe07.lg a...[color=blue]
        >
        > Where the derived dtor is called in both instances.[/color]

        virtual ~base() { std::cout << "b dtor" << std::endl; }
        [color=blue]
        > But, yes, the base dtor does get called in either case either.
        >[/color]

        (Sorry, left out that one line)


        Comment

        • Ron Natalie

          #19
          Re: why virtual base dtor gets called?

          Jim Langston wrote:
          [color=blue][color=green]
          >>Each subobject above recursively constructs it's subobjects
          >>(with the exception of avoiding duplicate construction of
          >>the virtual bases).
          >>
          >>There is nothing the program can do to change that ordering
          >>(within defined behavior).
          >>
          >>
          >>Objects are destructed in precisely the REVERSE ORDERING.
          >>[/color]
          > I just wrote a program and compiled and ran to test this theory, and it
          > seems
          > that "Objects are destructed in precisely the REVERSE ORDERING" is
          > not always true. Here is the program:
          >[/color]
          I was referring to the order of destruction of subobjects in
          an object.

          Comment

          • Ron Natalie

            #20
            Re: why virtual base dtor gets called?

            Jim Langston wrote:
            [color=blue]
            >
            > int _tmain(int argc, _TCHAR* argv[])
            > {
            > base* b;
            > derived* d;
            >
            > b = new derived;
            > delete b;
            >[/color]
            This is UNDEFINED BEHAVIOR... your program is incorrect
            and there is no point in even conjecture as to what
            the observable behavior is.

            It has no bearing on the original problem or my answer.

            Comment

            • Jim Langston

              #21
              Re: why virtual base dtor gets called?


              "Ron Natalie" <ron@spamcop.ne t> wrote in message
              news:42B09FB8.9 020306@spamcop. net...[color=blue]
              > Jim Langston wrote:
              >[color=green]
              >>
              >> int _tmain(int argc, _TCHAR* argv[])
              >> {
              >> base* b;
              >> derived* d;
              >>
              >> b = new derived;
              >> delete b;
              >>[/color]
              > This is UNDEFINED BEHAVIOR... your program is incorrect
              > and there is no point in even conjecture as to what
              > the observable behavior is.
              >
              > It has no bearing on the original problem or my answer.[/color]

              What part of it is undefined behavior? AFAIK everything I did in my
              program follows ANSI C and the behavior that resulted. If I'm doing
              something undefined I wanna know what it is so I won't do it anymore.


              Comment

              • roberth+news@ifi.uio.no

                #22
                Re: why virtual base dtor gets called?

                Jim Langston <tazmaster@rock etmail.com> wrote:
                |
                | "Ron Natalie" <ron@spamcop.ne t> wrote in message
                | news:42B09FB8.9 020306@spamcop. net...
                | > Jim Langston wrote:
                | >
                | >>
                | >> int _tmain(int argc, _TCHAR* argv[])
                | >> {
                | >> base* b;
                | >> derived* d;
                | >>
                | >> b = new derived;
                | >> delete b;
                | >>
                | > This is UNDEFINED BEHAVIOR... your program is incorrect
                | > and there is no point in even conjecture as to what
                | > the observable behavior is.
                | >
                | > It has no bearing on the original problem or my answer.
                |
                | What part of it is undefined behavior? AFAIK everything I did in my
                | program follows ANSI C and the behavior that resulted. If I'm doing
                | something undefined I wanna know what it is so I won't do it anymore.

                From § 5.3.5.3 (about delete expressions):
                if the static type of the operand is different from its dynamic type,
                the static type shall be a base class of the operands dynamic type
                and the static type shall have a virtual destructor or the behavior
                is undefined.

                Since the static type of *b is base, and the dynamic is derived, base
                ought to have a virtual destructor. Btw: This is from the C++ standard,
                not C.
                --
                Robert Bauck Hamar

                Comment

                • Ron Natalie

                  #23
                  Re: why virtual base dtor gets called?

                  Jim Langston wrote:[color=blue]
                  > "Ron Natalie" <ron@spamcop.ne t> wrote in message
                  > news:42B09FB8.9 020306@spamcop. net...
                  >[color=green]
                  >>Jim Langston wrote:
                  >>
                  >>[color=darkred]
                  >>>int _tmain(int argc, _TCHAR* argv[])
                  >>>{
                  >>> base* b;
                  >>> derived* d;
                  >>>
                  >>> b = new derived;
                  >>> delete b;
                  >>>[/color]
                  >>
                  >>This is UNDEFINED BEHAVIOR... your program is incorrect
                  >>and there is no point in even conjecture as to what
                  >>the observable behavior is.
                  >>
                  >>It has no bearing on the original problem or my answer.[/color]
                  >
                  >
                  > What part of it is undefined behavior? AFAIK everything I did in my
                  > program follows ANSI C and the behavior that resulted. If I'm doing
                  > something undefined I wanna know what it is so I won't do it anymore.
                  >
                  >[/color]
                  Deleting a derived object through a pointer to a base class is undefined
                  behavior when the base class doesn't have a virtual destructor.

                  Comment

                  • Clark S. Cox III

                    #24
                    Re: why virtual base dtor gets called?

                    On 2005-06-15 18:15:30 -0400, "Jim Langston" <tazmaster@rock etmail.com> said:
                    [color=blue]
                    >
                    > "Ron Natalie" <ron@spamcop.ne t> wrote in message
                    > news:42B09FB8.9 020306@spamcop. net...[color=green]
                    >> Jim Langston wrote:
                    >>[color=darkred]
                    >>>
                    >>> int _tmain(int argc, _TCHAR* argv[])
                    >>> {
                    >>> base* b;
                    >>> derived* d;
                    >>>
                    >>> b = new derived;
                    >>> delete b;
                    >>>[/color]
                    >> This is UNDEFINED BEHAVIOR... your program is incorrect
                    >> and there is no point in even conjecture as to what
                    >> the observable behavior is.
                    >>
                    >> It has no bearing on the original problem or my answer.[/color]
                    >
                    > What part of it is undefined behavior?
                    >[/color]
                    I notice two things:

                    1) The name "_tmain", if in the global namespace, is reserved for implementors.
                    2) If base does not have a virtual destructor, then "delete b" is UB.

                    AFAIK everything I did in my[color=blue]
                    > program follows ANSI C and the behavior that resulted.
                    >[/color]
                    I hope that you meant ANSI C++ there :)

                    If I'm doing something undefined I wanna know what it is so I won't
                    do it anymore.[color=blue]
                    >
                    >[/color]
                    --
                    Clark S. Cox, III
                    clarkcox3@gmail .com

                    Comment

                    • Stephen Howe

                      #25
                      Re: why virtual base dtor gets called?

                      > That was a typo or rather a mistake. I meant a base B pointer to D. As[color=blue]
                      > in...
                      >
                      > int main(int argc, char* argv[])
                      > {
                      > B* p_d = new D;
                      >
                      > delete p_d;
                      >
                      > return 0;
                      > }[/color]

                      Following your arguments: you are wrong.
                      You said, "You are describing a non-virtual d~tor. Only D's d~tor would be
                      invoke."

                      You know what the standard says ?
                      It says that it is UNDEFINED.
                      That means you cannot conclude "Only D's d~tor would be invoke." if B lacks
                      a virtual destructor and you have the above code.
                      Anything is legitimate.
                      It may well be that on your implementation that only D's dtor is invoked but
                      that is just _THAT_ implementation.

                      SH


                      Comment

                      • Stephen Howe

                        #26
                        Re: why virtual base dtor gets called?

                        > ..., or else the *derived* class destructor will not get invoked.

                        "Or else" nothing. It is undefined behaviour according to C++ standard.
                        Nothing can be concluded as to how it behaves.

                        SH


                        Comment

                        • Jim Langston

                          #27
                          Re: why virtual base dtor gets called?


                          "Clark S. Cox III" <clarkcox3@gmai l.com> wrote in message
                          news:2005061519 100450073%clark cox3@gmailcom.. .[color=blue]
                          > On 2005-06-15 18:15:30 -0400, "Jim Langston" <tazmaster@rock etmail.com>
                          > said:
                          >[color=green]
                          >>
                          >> "Ron Natalie" <ron@spamcop.ne t> wrote in message
                          >> news:42B09FB8.9 020306@spamcop. net...[color=darkred]
                          >>> Jim Langston wrote:
                          >>>
                          >>>>
                          >>>> int _tmain(int argc, _TCHAR* argv[])
                          >>>> {
                          >>>> base* b;
                          >>>> derived* d;
                          >>>>
                          >>>> b = new derived;
                          >>>> delete b;
                          >>>>
                          >>> This is UNDEFINED BEHAVIOR... your program is incorrect
                          >>> and there is no point in even conjecture as to what
                          >>> the observable behavior is.
                          >>>
                          >>> It has no bearing on the original problem or my answer.[/color]
                          >>
                          >> What part of it is undefined behavior?
                          >>[/color]
                          > I notice two things:
                          >
                          > 1) The name "_tmain", if in the global namespace, is reserved for
                          > implementors.[/color]

                          Ahh, well, I simply let M$ VC++ .net 2003 create a console program for me
                          and
                          threw in the code, cimpiled and ran. I didnt' think to check how it mangled
                          main. My bad.
                          [color=blue]
                          > 2) If base does not have a virtual destructor, then "delete b" is UB.[/color]

                          So, then, if I *always* give a base class that is going to have derived
                          classes a virtual
                          destructor then I"ll be in ANSI compliance and DB. Good to know. I"ll try
                          to make sure
                          I use virtual dtors on base classes.
                          [color=blue]
                          > AFAIK everything I did in my[color=green]
                          >> program follows ANSI C and the behavior that resulted.
                          >>[/color]
                          > I hope that you meant ANSI C++ there :)[/color]

                          Yeah, I did. Type there.

                          Thanks for the info.


                          Comment

                          • Howard

                            #28
                            Re: why virtual base dtor gets called?


                            "Stephen Howe" <sjhoweATdialDO TpipexDOTcom> wrote in message
                            news:42b0be01$0 $281$cc9e4d1f@n ews.dial.pipex. com...[color=blue][color=green]
                            >> ..., or else the *derived* class destructor will not get invoked.[/color]
                            >
                            > "Or else" nothing. It is undefined behaviour according to C++ standard.
                            > Nothing can be concluded as to how it behaves.
                            >
                            > SH
                            >[/color]

                            Sorry, you're correct. It's undefined behavior.
                            -Howard


                            Comment

                            Working...