CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Apr 2003
    Location
    Sydney, Australia
    Posts
    151

    Protected Virtual destructors Q.

    I'm aware of the common problem...

    Code:
    class A {
    public:
      A();
      ~A();
    
        virtual void x();
    };
    
    class B: public A {
    public:
       B();
       ~B();
    
        virtual void x();
    };
    
    A* pA = new B;
    delete pA;  //~B() never called;
    Lets say B should not have been virtual & derived from; but it happened anyway.

    Someone told me that declaring the destructor for A protected prevents inheritance at compile time... but wouldn't that disallow the object to be created altogether?

    I'm a bit confused, could someone please shed some light on this?

    Thanks

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Protected Virtual destructors Q.

    Someone told me that declaring the destructor for A protected prevents inheritance at compile time... but wouldn't that disallow the object to be created altogether?
    It does not prevent inheritance but it does prevent the creation of objects of type A.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Apr 2003
    Location
    Sydney, Australia
    Posts
    151

    Re: Protected Virtual destructors Q.

    Thanks for the response.

    In that case... is there any "simple" way to prevent people deriving classes from object A?

  4. #4
    Join Date
    May 2008
    Posts
    7

    Re: Protected Virtual destructors Q.

    As far as I know, If you declare a constructor protected you won't be able to instantiate that class directly with the constructor, but you will be able to instantiate a class derived from that one directly with the constructor.

    I other words, if the constructor is protected this means it is not for public access, unless for a derived class. So it's like it is private, and if it is private you can't create objects directly with the constructor. To create an object of that class you should use a public method from that class which will call the constructor.

    Home this makes sense for you.

  5. #5
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Protected Virtual destructors Q.

    In that case... is there any "simple" way to prevent people deriving classes from object A?
    Read Stroustrup's answer to the FAQ: Can I stop people deriving from my class?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  6. #6
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Protected Virtual destructors Q.

    Stroustrup's answer is (of course ) the correct one.

    But if you are willing to make your user utilize a factory method to create the object then private constructors will do the trick.

    This DOES impose some significant real-worl limitations on how the class can be used, but if utilized consistantly it can form the basis for a robust design.

    As an example, if you allow users to create instances either automatically or via calles to new, then it can be difficult (if not impossible) to implement many DI (dependancy injection) patterns. Forcing users to always you a factory provides the basis for making that factory dynamic.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  7. #7
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: Protected Virtual destructors Q.

    I had to look this up, so I thought I'd just share a point regarding the Stroustrup solution above. This is for the benefit of those who don't already know this:

    The reason why Usable_lock has to be a virtual base class of Usable is this statement from the Standard:

    Quote Originally Posted by C++ standard 12.6.2/6
    All sub-objects representing virtual base classes are initialized by the constructor of the most derived class.
    This means that, under "normal" circumstances, Usable is the most derived class and is responsible for initialising Usable_lock. This is OK, since Usable is a friend of Usable_lock. When we try to derive from Usable, however, this new class becomes the most derived and is responsible for initialising Usable_lock - something it can't do, because it's not a friend.

    If Usable did not inherit virtually from Usable_lock, then it would always be responsible for initialising it, so the trick wouldn't work.
    Last edited by Graham; May 13th, 2008 at 06:47 AM. Reason: Edited for spolling.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  8. #8
    Join Date
    Mar 2003
    Location
    India {Mumbai};
    Posts
    3,871

    Re: Protected Virtual destructors Q.

    "Declaring a private destructor." would be the answer to:

    "How to prevent stack allocation of my class?"
    My latest article: Explicating the new C++ standard (C++0x)

    Do rate the posts you find useful.

  9. #9
    Join Date
    Apr 2000
    Location
    Frederick, Maryland
    Posts
    507

    Re: Protected Virtual destructors Q.

    Quote Originally Posted by Ajay Vijay
    "Declaring a private destructor." would be the answer to:

    "How to prevent stack allocation of my class?"
    Not exactly you can still create a object of a class with private destructor on stack with the help of friend class. Take a look at this example, here even constructor is also private.

    Code:
    class FriendClass;
    
    class PrivateDtor
    {
    private:
    	PrivateDtor()
    	{
    		std::cout << "PrivateDtor::PrivateDtor" << std::endl;
    	}
    
    	~PrivateDtor()
    	{
    		std::cout << "PrivateDtor::~PrivateDtor" << std::endl;
    	}
    	friend class FriendClass;
    };
    
    class FriendClass
    {
    private:
    	PrivateDtor m_objPrivateDtor;
    };

  10. #10
    Join Date
    Mar 2003
    Location
    India {Mumbai};
    Posts
    3,871

    Re: Protected Virtual destructors Q.

    Well, the class itself is assigning "rights" to other class (or function).

    What I explained was "denying" everyone to create stack instance.
    My latest article: Explicating the new C++ standard (C++0x)

    Do rate the posts you find useful.

  11. #11
    Join Date
    Apr 2000
    Location
    Frederick, Maryland
    Posts
    507

    Re: Protected Virtual destructors Q.

    Quote Originally Posted by Ajay Vijay
    Well, the class itself is assigning "rights" to other class (or function).

    What I explained was "denying" everyone to create stack instance.
    You are absolutely right. I just wanted to show how it is possible using friend classes i.e. "denying everyone other than friends". There is even one non-standard way too, you can compile this code in even VC 2008, but again it is non-standard.

    Code:
    template <typename T>
    class PrivateDtor
    {
    private:
    	PrivateDtor()
    	{
    		std::cout << "PrivateDtor::PrivateDtor" << std::endl;
    	}
    
    	~PrivateDtor()
    	{
    		std::cout << "PrivateDtor::~PrivateDtor" << std::endl;
    	}
    	friend typename T;
    };
    
    class FriendClass
    {
    private:
    	PrivateDtor<FriendClass> m_objPrivateDtor;
    };
    Here "friend typename T;" is a non standard way.

  12. #12
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Protected Virtual destructors Q.

    Quote Originally Posted by Ajay Vijay
    "Declaring a private destructor." would be the answer to:

    "How to prevent stack allocation of my class?"

    OF course this means that when you new and object onto the heap, you can NOT delete it, and a forcing a memory leak....

    ps: For those interested, read Scott Meyer's "Effective C++" for a good explanation of why it is IMPOSSIBLE to create usuable objects that are forced to either the stack or the heap.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured