<< PreviousNext >>

Answer to Reference counting trouble

The reason why the new-statement does not compile is because of what happens in case of exceptions from the constructor. We could implement the behavior of new like this:

template <class T>
T *alloc() {
  void *memory = T::operator new(sizeof(T));
  T *obj = (T*)memory;
  try {
    // This executes T's constructor without allocating new memory.
    // It is called 'placement new'. Think of it as obj->T(), which is
    // actually not legal in C++.
    new (obj) T();
  } catch (...) {
    // Note that we do not call T::~T here, since we have not fully
    // constructed the object!
    T::operator delete(memory);
    throw;
  }
}

Here, it is clear why we need access to operator delete even if we only call new. If there is an exception in the constructor, we have to deallocate the object as well, and that requires us to be able to call operator delete, which is private.

The simple way of solving this is of course to not override operator delete, but that allows for programmers to use delete on refcounted object by mistake. At first I thought that declaring the destructor of the RefObject as protected to disallow this kind of constructs, but derived classes will declare public destructors by default. So overriding destructors in all derived classes is possible, but not a nice solution. I have actually not yet found a nice way of preventing delete on specific types yet.

Problem

Comments

New comment

You can use GitHub flavored markdown here. Parsed by Parsedown, which does not support all of GitHub's features. For example, specifying the language of code listings is not supported.

Name: