Jump to content
  • Advertisement
Sign in to follow this  
GenuineXP

Avoiding Virtual Destructor with boost::noncopyable

This topic is 3804 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm just wondering if this works the way I think it does. :-) If I have a class that I don't want to allow to be copied, deriving from boost::noncopyable does the trick. If boost::noncopyable is the only base though, can I avoid the vtable and virtual destructor altogether via private inheritance?
class widget : private boost::noncopyable {
public:
    widget();
    ~widget(); // Not virtual!
};
Doesn't this result in widget having a hidden boost::noncopyable member? And, if this is true, doesn't it still make it uncopyable since the compiler cannot deduce how to copy this member? I know avoiding a vtable and virtual destructor may not be warranted, but if I can, why not? :-) Thanks!

Share this post


Link to post
Share on other sites
Advertisement
Well, sure. You could also literally have a boost::noncopyable member. But why bother? boost::noncopyable doesn't declare a virtual destructor, so there won't be a virtual destructor unless you declare one. And the only reason you'd declare one (other than actually needing one further down the inheritance chain) is if you planned to pass around boost::noncopyable pointers, which would be bizarre in the extreme.

Share this post


Link to post
Share on other sites
struct MyNonCopyableFoo {
private:
MyNonCopyableFoo(const MyNonCopyableFoo &ff) {}
... operator=(...) {}
};


Boost is convenient, but one doesn't always have to hang on to it for everything.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
struct MyNonCopyableFoo {
private:
MyNonCopyableFoo(const MyNonCopyableFoo &ff) {}
... operator=(...) {}
};


Boost is convenient, but one doesn't always have to hang on to it for everything.

lol, I've thought about this also. It is pretty trivial to implement an uncopyable class.

Thanks for the insight.

EDIT:

One good thing about using boost::noncopyable is that it makes what you're trying to accomplish very clear.

Share this post


Link to post
Share on other sites
Quote:
Original post by GenuineXP
I'm just wondering if this works the way I think it does. :-)

If I have a class that I don't want to allow to be copied, deriving from boost::noncopyable does the trick. If boost::noncopyable is the only base though, can I avoid the vtable and virtual destructor altogether via private inheritance?

*** Source Snippet Removed ***
Doesn't this result in widget having a hidden boost::noncopyable member? And, if this is true, doesn't it still make it uncopyable since the compiler cannot deduce how to copy this member?

I know avoiding a vtable and virtual destructor may not be warranted, but if I can, why not? :-)

Thanks!


Inheritance results in the derived class having a sort-of "member" of the base class type, sometimes called "the base class part of" the object (when there is only one), or "a base" (analogously to "a member"). That has nothing to do with whether the inheritance is public, protected or private.

The compiler can't copy boost::noncopyable objects, and thus it can't copy objects which include them as a member or base. Using it as a base rather than a member is considered idiomatic for some reason.

boost::noncopyable doesn't declare anything virtual, because it doesn't need to. The way to avoid creating a vtable and so forth in the derived class is to do nothing, i.e. not put in a virtual destructor. (Note that in C++, we have the rule of "once virtual, always virtual": in order to have a base that is virtual, we have to include that base in the object's data layout, which means we have to allow for a vtable anyway - assuming that it's implemented that way - so we've already paid the cost; thus C++ doesn't ever make the derived class non-virtual, since you can't save anything that way.)

Of course, multiple inheritance complicates things, but the basic principle is the same: inheriting from boost::noncopyable publically, protected-ly or privately, or including a member of type boost::noncopyable, makes the class non-copyable, and incurs no overhead, unless you confuse yourself and explicitly add some. :)

Writing a *non*-virtual, empty destructor can't hurt, of course (because you still haven't added any virtual functionality, so you won't pay that overhead), but it's also useless: its effect is identical to what you'd get by not writing a destructor at all.

Share this post


Link to post
Share on other sites
Quote:

Using it as a base rather than a member is considered idiomatic for some reason.


Probably to take advantage of the empty base optimisation. C++ compilers must give regular members different addresses AFAIK.

Share this post


Link to post
Share on other sites
Inheritace makes more conceptual sense to me her than composition - I think it makes the code more self documenting.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!