Pure virtual base class destructor

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • arnaudk
    Contributor
    • Sep 2007
    • 425

    Pure virtual base class destructor

    How come it's possible to have a base class with a pure virtual destructor and nonetheless one has to implement the destructor? Doesn't pure virtual mean that there is no implementation of that method in the base class and the implementation is left entirely up to derived classes?
    [code=cpp]
    class Base
    {
    public:
    Base() {}
    virtual ~Base() = 0; // pure virtual destructor
    }
    Base::~Base() // <-- Linktime error if
    {} // this implementation is omitted!
    [/code]

    In fact, it seems I can provide an implementaiton of any pure virtual base class method without error although the linker doesn't complain if I do not, like it does with the destructor.
  • RRick
    Recognized Expert Contributor
    • Feb 2007
    • 463

    #2
    This looks like one of those 'gotchas' where one rule takes precedence over another rule. The pure abstract does not "normally" need the base class to define the method.

    Your problem is that you are playing around with the mandatory methods that every class needs. For example, every class needs a destructor and at least one constructor. If you don't define the method, then the compiler will make one for you. If you declare the method yourself (as you did with the pure destructor), then you also have to supply a definition. The compiler won't do this for you.

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      Originally posted by arnaudk
      Doesn't pure virtual mean that there is no implementation of that method in the base class and the implementation is left entirely up to derived classes?
      That's not what pure virtual means.

      Here is the correct meaning: The pure virtual method cannot be called using an instance of the class.

      That doesnt't say anything about an implementation. In fact, a pure virtual function can have an implementation and you can call it using an instance of another class, like the derived class:

      [code=cpp]
      class Base
      {
      public:
      virtual void Hello() = 0;
      };
      void Base::Hello()
      {
      cout << "arnaudk" << endl;
      }

      clase Derived :public Base
      {
      public:
      void Hello();
      };

      void Derived::Hello( )
      {
      this->Base::Hello( ); //call base class function
      }
      [/code]

      In the case of your pure virtual destructor, that doesn't exist since you cannot override a class destructor from an other class. I expect some compilers will producd an error if you do this.

      The virtual destructor in the base class tells the compiler that when you delete a base pointer, that you want the derived destructors called. If you don't do this, when you delete the base pointer only the base destructor is called.

      There is simply no way for the compiler to figure this out on the basis of a base pointer alone.

      Comment

      • arnaudk
        Contributor
        • Sep 2007
        • 425

        #4
        Thank you. Previously, I was under the impression that one could not have instances of a class with pure virtual methods. That clears up my confusion!

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Originally posted by arnaudk
          Previously, I was under the impression that one could not have instances of a class with pure virtual methods. That clears up my confusion!
          You have the correct impression: You cannot have instances of a class with pure virtual methods.

          You have to read what I said carefully. What I said was you cannot call a pure virtual method with an instance of the class. But that you can call this pure virtual method with an instance of a derived class.

          What happens is, the compiler does not trust you to behave. It's a very suspicious piece of software. It knows, sure as heck, that if you get to create an instance of a class with a pure virtual method, that later on you will you that object to call the pure virtual function. So, the compiler won't let you create the object in the first place.

          Comment

          • arnaudk
            Contributor
            • Sep 2007
            • 425

            #6
            Indeed, I soon discovered I can not instantiate abstract class as I previously thought.

            But if I can not create instances of an abstract base class, how can I access the implementation of its pure virtual methods? I mean, the compiler complains if I don't provide an implementation of those pure virtual methods in derived classes, and those will override any base class implementation when called.
            It seems to me the only time you ever see the base class implementation of a pure virtual base class method is when a pure virtual destructor is called.

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              Look at nmy Post #3.

              The base class implements the pure virtual method.

              The derived class overrides this with its own method. However, that pure virtual method is still a function and it is a base class function and your are in the derived class so you can call the base class function from your derived class.

              Take my Post #3 and add this main():
              [code=cpp]
              int main()
              {
              Derived obj.
              obj.Hello();
              }
              [/code]

              Keep in mind a derived object contains an embedded base object. The derived object can call methods in its own embedded base object by using base class methods. So here the derived object is simple calling a base class method on itself.

              It the Base objects that you can't create.

              Comment

              • arnaudk
                Contributor
                • Sep 2007
                • 425

                #8
                Your post #3 was indeed clear about that. Thanks again.

                Comment

                Working...