[Telepathy] tq-qt4 refcount proposal
Andre Moreira Magalhaes
andre.magalhaes at collabora.co.uk
Mon Apr 13 11:24:43 PDT 2009
Jonathon Jongsma wrote:
> Andre Moreira Magalhaes wrote:
>>> [explicit inline SharedPtr(T *d) : d(d) { if (d) { d->ref(); } }]
>>> boost::shared_ptr uses a templated constructor for this case (e.g.
>>> template
>>> <class Y> SharedPtr(Y *d) ...) which allows it to somehow remember
>>> the actual
>>> pointer type passed so that if it was a different type that is
>>> convertible to
>>> T*, it will call delete with its original type and thus will not
>>> leak even if Y
>>> does not have a virtual destructor). Granted, they probably use some
>>> black magic
>>> to accomplish this, but it might be worth considering. For example,
>>> consider
>>> this contrived example:
>>> class A {};
>>> class B : public A {
>>> public:
>>> B() : x(new int[1000]) {}
>>> ~B() { delete [] x; }
>>> private:
>>> int * x;
>>> }
>>> // This will leak 1000*sizeof(int) when it goes out of scope
>>> SharedPtr<A> shared(new B());
>>> // whereas this does not leak:
>>> boost::shared_ptr<A> boost_shared(new B());
>>>
>> Done
>
> OK, you did change the signature of the constructor to the same form
> used by boost::shared_ptr, but it doesn't appear that you made any
> changes internally to remember this type, so I'm not sure you actually
> gained anything by making this change. In the case I mentioned above,
> I believe you will still leak. It's probably best to either go back
> to the original signature and make the docs clear about this
> limitation, or go in all the way and implement the black magic from
> boost.
>
Done, removed this black magic and back to normal constructor.
>>> [template<class X>
>>> inline SharedPtr(const SharedPtr<X> &o)]
>>> I don't think this constructor is a good idea. I assume this is
>>> designed so that
>>> you can easily convert from a derived class pointer to a base class
>>> pointer as you
>>> would with raw pointers, but I think it's much better to make the
>>> programmer state
>>> explicitly what they want to do. And in any case, dynamic_cast is
>>> probably the more
>>> appropriate cast in this situation. See also
>>> boost::static_pointer_cast/dynamic_pointer_cast/etc or
>>> Glib::RefPtr::cast_static/cast_dynamic/etc
>>>
>> Done
>
> OK, I notice that you removed this constructor, which is good, but I
> didn't see any added API for doing the casting properly. For example,
> Glib::RefPtr<T>::cast_dynamic(RefPtr<U>). This is mostly syntactic
> sugar, but I think it's worthwhile since look how ugly your code got
> after making this change:
>
> - mChan = pc->channel();
> + mChan = StreamedMediaChannelPtr(
> + dynamic_cast<StreamedMediaChannel*>(pc->channel().data()));
>
> Whereas, if you added some casting helpers, you could make it a little
> bit more palatable. Here's how it would look with Glib::RefPtr-style
> casting helpers:
> mChan = StreamedMediaChannelPtr::cast_dynamic(pc->channel());
> or boost-style:
> mChan = dynamic_pointer_cast<StreamedMediaChannel>(pc->channel());
>
> I think either of these two options look considerably nicer than the
> code above, but that's partly personal taste, I suppose.
>
Done, added dynamic, static and const cast helper methods
> Hope that helps.
>
It really helped, thanks
http://git.collabora.co.uk/?p=user/andrunko/telepathy-qt4.git;a=shortlog;h=refs/heads/shared
BR
Andrunko
More information about the telepathy
mailing list