looser throw specifier in gcc 4.0.1

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • pnayak
    New Member
    • Apr 2008
    • 9

    looser throw specifier in gcc 4.0.1

    Hi All,

    Compiling the code below should result in the "looser throw specifier" error from the gcc compiler. It does give me that error if I un-comment the destructor in the derived class. But the default destructor created by the compiler should will be essentially the same. So I'm wondering why this compiles.
    Code:
    #include <iostream>
    
    class Base {
        public:        Base()  { std::cout << "Constructing base" << std::endl; };        virtual ~Base() throw() { std::cout << "Destroying base" << std::endl; };
    };
    
    class Derived : public Base {
        public:
            Derived() { std::cout << "Constructing derived" << std::endl; };
            //~Derived() { std::cout << "Destroying derived" << std::endl; };
    };
    
    int main()
    {
        Base *b = new Derived();
        delete b;
    }
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    There is a destructor in your base class that has a throw() specifier.

    When you override that destructor with Derived::~Deriv ed you must have the same throw() specifier as the overriden function. Your derived destructor has no throw specifier at all, hence the error.

    Note that since the base class has a virtual destructor and the derived class does not, if you ever create a Derived object as a Derived object, the base class destructor will not be called.

    I therefore recommend for derived classes from base classes with virtual destructors that you make all derived methods private to avoid the possibiity of someone creating a Derived object directly and calling Derived methods. You can call Derived private methods from Base public methods since the access specifiers are ignored for purposes of overloading. Like this:

    Code:
     class Base {
         public:        Base()  { std::cout << "Constructing base" << std::endl; }; 
    					virtual ~Base() throw() { std::cout << "Destroying base" << std::endl; };
    					virtual void Method() {cout << "Base" << std::endl;}
     };
    
     class Derived : public Base {
        public:
             Derived() { std::cout << "Constructing derived" << std::endl; };
            //~Derived() { std::cout << "Destroying derived" << std::endl; };
     private:
    		 void Method() {cout << "Derived" << std::endl;}
     };
     
     int main()
     {
          Base *b = new Derived();
    	  b->Method();
       delete b;
      }

    Comment

    Working...