views:

71

answers:

2

At work we have a base class, let's call it IntrusiveBase, that acts something like a mixin to allow a class to be stored in a boost:intrusive_ptr. That is, it provides its subclasses with a ref count and defines intrusive_ptr_add_ref and intrusive_ptr_release overloads. The problem is that it is too easy for someone to forget that a particular subclass inherits from IntrusiveBase, and they then store it in some other smart pointer like a scoped_ptr or shared_ptr. That doesn't work because, for example, the scoped_ptr will delete the object when it goes out of scope no matter what the ref count happens to be. We have an assertion in ~IntrusiveBase that the ref count is one, but this is not foolproof because oftentimes there will end up only being the original instance by the time the scoped_ptr goes out of scope. This leaves an insidious failure waiting to happen those few times that the ref count is not one.

Is there any way that I can cause a compile-time failure if someone accidentally does this? Even if I have to do something repetitively for each of the major smart pointer classes, it would be worth it.

+4  A: 

Even if I have to do something repetitively for each of the major smart pointer classes, it would be worth it.

In that case, you can specialize them on your InstrusiveBase inheriting types.

  namespace boost
  {
    template<>
    class scoped_ptr<InstrusiveBaseSubclass> { }; // scoped_ptr<InstrusiveBaseSubClass> p(new InstrusiveBaseSubClass) won't compile, neither will p->, p.get() etc.

  }

This is annoying but it's macro-able, e..g:

 class A : InstrusiveBase
 { 
     ...
 }
 NO_SCOPED_PTR(A)
 NO_SHARED_PTR(A)
Logan Capaldo
+5  A: 

Another option would be to overload new and delete for those classes and make delete private or protected. instrusive_ptr_release could then be made a friend function or similar technique used to actually invoke delete when the ref count dropped to zero.

Logan Capaldo
So, I tried this, but it doesn't seem to work. I ran into this problem: http://stackoverflow.com/questions/1820069/public-operator-new-private-operator-delete-getting-c2248-can-not-access-priva
SCFrench