clarification - calling virtual function from destructor

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

    clarification - calling virtual function from destructor

    Hello


    class A

    {

    public:

    virtual void Func1() = 0;

    void Func1Caller()

    {

    Func1();

    }

    ~A()

    {

    Func1Caller();

    }

    };

    class B : public A

    {

    public:

    virtual void Func1()

    {

    printf("this is func1\n");

    }

    };

    int main()

    {

    B t;

    return 0;

    }



    It seems that VC is not allowing Func1Caller() to call Func1() from the
    destructor.
    Don't know if this a C++ issue or a compiler issue.

    Can someone clarify and provide a workaround?

    --
    Elias


  • Alf P. Steinbach

    #2
    Re: clarification - calling virtual function from destructor

    On Fri, 6 Feb 2004 12:16:46 +0200, "lallous" <lallous@lgwm.o rg> wrote:
    [color=blue]
    >class A
    >{
    >public:
    >virtual void Func1() = 0;
    >void Func1Caller()
    >{
    >Func1();
    >}
    >~A()
    >{
    >Func1Caller( );
    >}
    >};[/color]

    The destructor here has undefined behavior because it's calling
    a pure virtual function.

    With a good C++ compiler this will cause a run-time error, but
    formally it could do anything (including seemingly "working").

    Hint: get your indentation in order before worrying about such
    things, and also see the FAQ, which answers such questions.

    Comment

    • lallous

      #3
      Re: clarification - calling virtual function from destructor

      "Alf P. Steinbach" <alfps@start.no > wrote in message
      news:40236bee.1 00362265@News.C IS.DFN.DE...[color=blue]
      > On Fri, 6 Feb 2004 12:16:46 +0200, "lallous" <lallous@lgwm.o rg> wrote:
      >[color=green]
      > >class A
      > >{
      > >public:
      > >virtual void Func1() = 0;
      > >void Func1Caller()
      > >{
      > >Func1();
      > >}
      > >~A()
      > >{
      > >Func1Caller( );
      > >}
      > >};[/color]
      >[/color]
      [color=blue]
      > The destructor here has undefined behavior because it's calling
      > a pure virtual function.[/color]
      But isn't the pure virtual function defined through class B?

      And you cannot create an instance of class A unless its pure virtual method
      is defined.
      [color=blue]
      >
      > With a good C++ compiler this will cause a run-time error, but
      > formally it could do anything (including seemingly "working").[/color]
      It did produce a runtime error.
      [color=blue]
      > Hint: get your indentation in order before worrying about such
      > things, and also see the FAQ, which answers such questions.[/color]
      The code is idented, but the NG composer got it unidented.

      I read C++ Lite FAQ but didn't know how to solve.

      --
      Elias


      Comment

      • Alf P. Steinbach

        #4
        Re: clarification - calling virtual function from destructor

        On Fri, 6 Feb 2004 12:47:13 +0200, "lallous" <lallous@lgwm.o rg> wrote:
        [color=blue]
        >I read C++ Lite FAQ but didn't know how to solve.[/color]

        See the section on constructors.

        Comment

        • lilburne

          #5
          Re: clarification - calling virtual function from destructor



          lallous wrote:[color=blue]
          > "Alf P. Steinbach" <alfps@start.no > wrote in message
          > news:40236bee.1 00362265@News.C IS.DFN.DE...
          >
          >[color=green]
          >>The destructor here has undefined behavior because it's calling
          >>a pure virtual function.[/color]
          >
          > But isn't the pure virtual function defined through class B?
          >
          > And you cannot create an instance of class A unless its pure virtual method
          > is defined.
          >[/color]

          When you enter A's destructor B has already been destroyed, it is no
          more, it is an ex-B.

          Comment

          • james

            #6
            Re: clarification - calling virtual function from destructor

            Every class is better has own constructor and deconstructor itself, even if
            compiler allow you do that. Class A func1 alway be called In your code. I
            revised your code for you. every class will call func1 itself. then you
            don't need to name"virturl" in class B.
            class A
            {
            public:
            virtual void Func1()
            {
            printf("this is class A");
            };
            void Func1Caller()
            {
            Func1();
            }
            ~A()
            {
            Func1Caller();
            }
            };

            class B : public A
            {
            public:
            B();
            ~B();
            void Func1(){ printf("this is class B\n");}
            B::B() {}
            B::~B(){ Func1Caller();}
            };

            int main()

            {
            B t;
            return 0;
            }


            Comment

            • Sharad Kala

              #7
              Re: clarification - calling virtual function from destructor


              "james" <jj6066@dcs.war wick.ac.uk> wrote in message
              news:c0017c$odl $1@mail.dcs.war wick.ac.uk...[color=blue]
              > Every class is better has own constructor and deconstructor itself, even if
              > compiler allow you do that. Class A func1 alway be called In your code. I
              > revised your code for you. every class will call func1 itself. then you
              > don't need to name"virturl" in class B.
              > class A
              > {
              > public:
              > virtual void Func1()
              > {
              > printf("this is class A");
              > };
              > void Func1Caller()
              > {
              > Func1();
              > }
              > ~A()
              > {
              > Func1Caller();
              > }
              > };
              >
              > class B : public A
              > {
              > public:
              > B();
              > ~B();
              > void Func1(){ printf("this is class B\n");}
              > B::B() {}
              > B::~B(){ Func1Caller();}
              > };
              >
              > int main()
              >
              > {
              > B t;
              > return 0;
              > }[/color]


              The code you posted won't even compile dear friend!
              As pointed by others calling pure virtual function inside a destructor is
              calling in for undefined behavior.


              Comment

              • Martijn Lievaart

                #8
                Re: clarification - calling virtual function from destructor

                On Fri, 06 Feb 2004 12:16:46 +0200, lallous wrote:
                [color=blue]
                > It seems that VC is not allowing Func1Caller() to call Func1() from the
                > destructor.
                > Don't know if this a C++ issue or a compiler issue.
                >
                > Can someone clarify and provide a workaround?[/color]

                It's normal C++ behaviour. At the time of the destructor (the same goes
                for the constrctor) the dynamic type is set to that of the destructor.
                What does that mean?

                class A
                {
                public:
                virtual f1() { puts("A"); }
                };

                class B
                {
                public:
                virtual f1() { puts("B"); }
                ~B()
                {
                f1(); // Prints B, we are a B, we are no longer a C
                A *p = this;
                p->f1(); // Again prints B, virtual functions still work,
                // we are a B, so calls B::f1
                }
                };

                class C
                {
                public:
                virtual f1() { puts("C"); }
                };

                int main();
                {
                C c;
                }

                When C gets destroyed, first the destuctor for C is executed, then the
                destructor for the B subobject *but* with it's type set to B, then the A
                subobject is destroyed, but with it's type set to A.

                Think about it. The C object is already destroyed, it would make a fine
                mess if virtual functions worked the way you assumed they do.

                HTH,
                M4

                Comment

                • james

                  #9
                  Re: clarification - calling virtual function from destructor

                  another example is more clear about virtual function
                  declareation is as yours
                  B mean;
                  A meam1;
                  B *meam2;
                  meam2=&meam1;
                  meam2->Func1(); // callB::Func1();
                  meam2=&A;
                  meam2->Func1(); //call A::Func1();


                  "james" <jj6066@dcs.war wick.ac.uk> ¦b¶l¥ó
                  news:c0017c$odl $1@mail.dcs.war wick.ac.uk ¤¤¼¶¼g...[color=blue]
                  > Every class is better has own constructor and deconstructor itself, even[/color]
                  if[color=blue]
                  > compiler allow you do that. Class A func1 alway be called In your code. I
                  > revised your code for you. every class will call func1 itself. then you
                  > don't need to name"virturl" in class B.
                  > class A
                  > {
                  > public:
                  > virtual void Func1()
                  > {
                  > printf("this is class A");
                  > };
                  > void Func1Caller()
                  > {
                  > Func1();
                  > }
                  > ~A()
                  > {
                  > Func1Caller();
                  > }
                  > };
                  >
                  > class B : public A
                  > {
                  > public:
                  > B();
                  > ~B();
                  > void Func1(){ printf("this is class B\n");}
                  > B::B() {}
                  > B::~B(){ Func1Caller();}
                  > };
                  >
                  > int main()
                  >
                  > {
                  > B t;
                  > return 0;
                  > }
                  >
                  >[/color]


                  Comment

                  • james

                    #10
                    Re: clarification - calling virtual function from destructor

                    I talked about virtual function, so it is not serious for formal porgram,
                    anyway thanks a lot
                    "Sharad Kala" <no.spam_sharad k_ind@yahoo.com > ¦b¶l¥ó
                    news:c002gs$10k j6e$1@ID-221354.news.uni-berlin.de ¤¤¼¶¼g...[color=blue]
                    >
                    > "james" <jj6066@dcs.war wick.ac.uk> wrote in message
                    > news:c0017c$odl $1@mail.dcs.war wick.ac.uk...[color=green]
                    > > Every class is better has own constructor and deconstructor itself, even[/color][/color]
                    if[color=blue][color=green]
                    > > compiler allow you do that. Class A func1 alway be called In your code.[/color][/color]
                    I[color=blue][color=green]
                    > > revised your code for you. every class will call func1 itself. then you
                    > > don't need to name"virturl" in class B.
                    > > class A
                    > > {
                    > > public:
                    > > virtual void Func1()
                    > > {
                    > > printf("this is class A");
                    > > };
                    > > void Func1Caller()
                    > > {
                    > > Func1();
                    > > }
                    > > ~A()
                    > > {
                    > > Func1Caller();
                    > > }
                    > > };
                    > >
                    > > class B : public A
                    > > {
                    > > public:
                    > > B();
                    > > ~B();
                    > > void Func1(){ printf("this is class B\n");}
                    > > B::B() {}
                    > > B::~B(){ Func1Caller();}
                    > > };
                    > >
                    > > int main()
                    > >
                    > > {
                    > > B t;
                    > > return 0;
                    > > }[/color]
                    >
                    >
                    > The code you posted won't even compile dear friend!
                    > As pointed by others calling pure virtual function inside a destructor is
                    > calling in for undefined behavior.
                    >
                    >[/color]


                    Comment

                    • james

                      #11
                      Re: clarification - calling virtual function from destructor

                      then I agree with Sharard Kala' opion. It is a bed idea to put virtual
                      function in destructor. see my another example at previou post.


                      Comment

                      • red floyd

                        #12
                        Re: clarification - calling virtual function from destructor

                        lilburne wrote:
                        [color=blue]
                        >
                        > When you enter A's destructor B has already been destroyed, it is no
                        > more, it is an ex-B.
                        >[/color]

                        It has ceased to "B"? Of course, it could just be pining for the fjords.

                        Comment

                        Working...