Note that there is nothing "safe" about what you are trying to do. If b is set to NULL then b->Dispose(); causes behaviour that is just as undefined as if b pointed to a deleted object.
–
Charles BaileyAug 25 '11 at 7:15

@Charles: Edited, waiting for review. This bug is not a part of a question, is it?
–
Janusz LenarAug 25 '11 at 8:41

Also, no need for SafeDispose to be a friend since Dispose is public.
–
Janusz LenarAug 25 '11 at 8:43

The real answer is that the Building is a subclass of UniquePointer but the Building* is a subclass of UniquePointer*. That's why you can't cast Building* to UniquePointer*& - it's not a polymorphism.
–
Janusz LenarAug 25 '11 at 8:49

@Charles: Yeah wasn't meant to be safe, it was just me experimenting with the language :) I wanted to know how systems like COM are implemented so I started off with a simple unique pointer, then later on I would have moved to a reference counting system.
–
SqueakySquakAug 25 '11 at 9:02

I see your point. The reason I wanted the reference to pointer was to be able to set that pointer to NULL but I obviously missed out all the side effects this could have.
–
SqueakySquakAug 25 '11 at 9:08

To answer the title of your question, you cannot bind a non-const reference to base to a derived class instance because you could then set that reference to a pointer to a base instance that isn't a derived. Consider this function:

void Renew(UniquePointer *& p) {
delete p;
p = new UniquePointer();
}

if you could pass it a pointer to Building you would be able to set it incorrectly to point to a UniquePointer instance.

As it has already been suggested the solution is to change your reference to a plain pointer. Not only this solves your problem, but it is also a better implementation of SafeDispose(); as you wrote it this function gave the false idea that you would always set to 0 all your UniquePointer instances. But what would happen if somebody wrote (assuming UniquePointer constructor was public for simplicity):

I could have probably given everything a better name than what I did. I intended SafeDispose to set the pointer to NULL and check for NULL, but I didn't consider the fact that the callee could have a copy of the pointer. But it is important to note that there is no sharing whatsoever, I was interested in a "singe ownership" system after reading Google's coding style.
–
SqueakySquakAug 25 '11 at 9:19

But &b is an rvalue of type Building** which you can't pass to a function taking a UniquePointer** for pretty much identical reasons that you can't bind a Building* to a non-const UniquePointer*&.
–
Charles BaileyAug 25 '11 at 7:36

Thanks for pointing this out. Adding a cast would probably fix this issue right ?! (updated sample code). Then I guess that wilx answer (by using a template) makes more sense.
–
Sebastien ThuilliezAug 25 '11 at 8:15

1

No, a cast doesn't fix the issue it creates a new one. The cast converts the pointer but the result of the cast is an rvalue and you can't then take the address of an rvalue.
–
Charles BaileyAug 25 '11 at 8:32