|
-
May 13th, 2008, 05:28 AM
#1
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
-
May 13th, 2008, 05:32 AM
#2
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.
-
May 13th, 2008, 05:36 AM
#3
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?
-
May 13th, 2008, 05:39 AM
#4
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.
-
May 13th, 2008, 05:48 AM
#5
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?
-
May 13th, 2008, 06:16 AM
#6
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
-
May 13th, 2008, 06:45 AM
#7
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:
 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
-
May 13th, 2008, 12:26 PM
#8
Re: Protected Virtual destructors Q.
"Declaring a private destructor." would be the answer to:
"How to prevent stack allocation of my class?"
-
May 13th, 2008, 01:09 PM
#9
Re: Protected Virtual destructors Q.
 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;
};
-
May 13th, 2008, 01:12 PM
#10
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.
-
May 13th, 2008, 01:27 PM
#11
Re: Protected Virtual destructors Q.
 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.
-
May 13th, 2008, 05:34 PM
#12
Re: Protected Virtual destructors Q.
 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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|