No no, you misunderstand. It's not as bad as that. What destructor shared_ptr calls depends on the declared type of the argument in its constructor, not the type of the shared_ptr itself. So, in an idiomatic spelling:
> shared_ptr<Foo> foo(new Bar(5));
everything works fine, because the argument is of type "Bar *" (that being the return type of the new expression).
It's only in the case of:
> Foo *foo_rawptr = new Bar(5);
> shared_ptr<Foo> foo(foo_rawptr);
that you get wrong behavior.
That is a feature of C++ the language: it lets you decide whether you want to keep track of the runtime type of the object or not. "Not" is a very important use-case: it allows you to use many of the features of C++ even in situations where adding a class-pointer word to every instance would be excessively expensive, or impossible (e.g. mmaping a file full of structs from disk).
So anyhow, the *default* is to not track the runtime-type. However, if you mark the destructor "virtual", then it *will* add a word to the size of the object instance to keep track of the actual type, and then delete will call the destructor for "Bar", even in the second case.
Taking shared_ptr out of the picture for simplification, the thing that doesn't work without a virtual destructor is:
> Bar *bar = new Bar(5);
> Foo *foo = bar;
> delete foo;
(that is: where the static type of the argument to delete is different from the dynamic type of the object).
Apache resigns from the Java Community Process executive committee
Posted Dec 15, 2010 3:06 UTC (Wed) by HelloWorld (guest, #56129)
[Link]
No no, you misunderstand. It's not as bad as that. What destructor shared_ptr calls depends on the declared type of the argument in its constructor, not the type of the shared_ptr itself.
Whoa! That is certainly a behaviour I didn't expect. Other smart pointer classes like boost::scoped_ptr or std::auto_ptr don't do this, and I really can't think of a reason for making shared_ptr behave that way. Do you know of any rationale for this behaviour?