I ran into a problem that caused some annoying segfaults.
[size=150]The Problem[/size]
Consider the following factory pattern (reduced for simplicity):
class Item
{
public:
static SharedPtr<Item> Item::create(Item_e item)
{
switch(item) {
case ITEM_FLOWER: return new FlowerItem;
/* etc */
}
return SharedPtr<Item>();
}
};
Now consider the following call to this factory method:
Item* item = Item::create(ITEM_FLOWER);
// Oh oh, the FlowerItem object was destroyed here
It shouldn’t be possible to convert SharedPtr to a raw pointer like this. This basically makes SharedPtr::Get() a useless method.
Furthermore, although not as bad as above, these implicit conversions allow for somewhat confusing code. For example:
SharedPtr<Foo> foo;
doAThing(foo);
Does doAThing(); take a raw pointer Foo* or a SharedPtr? We cannot know without looking up the function signature.
Or this:
Is foo_ a SharedPtr or a raw pointer? Again, we cannot know without looking at the definition of foo_.
[size=150]Proposed solution[/size]
I propose to make the following change to SharedPtr and WeakPtr. Change this:
to this:
This change will fix all of the problems explained above and at the same time it will still allow for code such as this:
SharedPtr<Item> item = Item::create(ITEM_FLOWER);
if(!item) // This is still valid!
return;
This change will force us to change these examples:
[code]// 1
SharedPtr foo;
doAThing(foo);
// 2
Foo* MyClass::SomeMethod() { return foo_; }[/code]
Into this:
[code]// 1
SharedPtr foo;
doAThing(foo.Get());
// 2
Foo* MyClass::SomeMethod() { return foo_.Get(); }[/code]
Which allows us to instantly see that if SharedPtr is being used or not.
If the dev team agrees, I shall go ahead and make this change.