--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
- Have Base inherit from SupportsWeakPtr<Base> and use base::AsWeakPtr to get a correctly-typed weak ptr. This works today, but doesn't support invalidating the weak ptrs at arbitrary times, which I need to do.
- Introduce WeakPtrFactory::AsWeakPtr() (modeled after base::AsWeakPtr()) like this:
template<typename Derived> WeakPtr<Derived> AsWeakPtr(Derived* ptr) {
typedef is_convertible<Derived, T&> convertible;
COMPILE_ASSERT(convertible::value,
AsWeakPtr_argument_needs_to_derive_from_base);
CHECK_EQ(static_cast<Derived*>(ptr_), ptr);
return WeakPtr<Derived>(weak_reference_owner_.GetRef(),
static_cast<Derived*>(ptr_));
}
I feel this is slightly ugly due to the fact that the factory essentially already has the pointer. I wouldn't want to introduce a type-parameterized GetWeakPtr() variant though, as that would encourage unsafe casting.I'm not feeling particularly happy with any of them, so I'm hoping somebody has better ideas or advice.Thanks,Mattias
--
I think that this still requires Derived to extend SupportsWeakPtr, which Mattias didn't want to do?Personally, I think that 1 is the way to go. A WeakPtrFactory doesn't necessarily need to vend pointers to its owner, it could vend them to any other object (i.e. in this case any other Base object), which might not be a Derived object. So it seems there is no fully type-safe way
--
- Cast the returned WeakPtr<Base> to a WeakPtr<Derived>. Not sure whether it's safe to assume different template instantiations to have the same memory layout?
- Have Base inherit from SupportsWeakPtr<Base> and use base::AsWeakPtr to get a correctly-typed weak ptr. This works today, but doesn't support invalidating the weak ptrs at arbitrary times, which I need to do.
- Introduce WeakPtrFactory::AsWeakPtr() (modeled after base::AsWeakPtr()) like this:
template<typename Derived> WeakPtr<Derived> AsWeakPtr(Derived* ptr) {
typedef is_convertible<Derived, T&> convertible;
COMPILE_ASSERT(convertible::value,
AsWeakPtr_argument_needs_to_derive_from_base);
CHECK_EQ(static_cast<Derived*>(ptr_), ptr);
return WeakPtr<Derived>(weak_reference_owner_.GetRef(),
static_cast<Derived*>(ptr_));
}
I feel this is slightly ugly due to the fact that the factory essentially already has the pointer. I wouldn't want to introduce a type-parameterized GetWeakPtr() variant though, as that would encourage unsafe casting.
Dear friends of tasks and weak ptrs (and chromium-dev)!Here's a question about weak ptrs vs. inheritance that I'm not sure we have a good answer for. Suppose I have the following:
1 class Base {2 protected:3 base::WeakPtrFactory<Base> weak_factory_;4
--
--
Some thoughts...
1- On one hand, casting between WeakPtr<A> and WeakPtr<B> shouldn't need to be anymore restrictive than static_cast'ing between A* and B*. WeakPtr is just a container for a raw pointer. The only thing it adds is a way to null out the raw pointer when the object it points to disappears.
2- The concern Wez raised is a good one. What does it mean to have a non-null WeakPtr<Derived> pointing to a Derived object that has already executed ~Derived? That seems like a problematic state.
#1 is what encouraged me to suggest WeakPtr<T>::From(const WeakPtr<U>&), but #2 makes me think we shouldn't support down-casting WeakPtr<Base> to WeakPtr<Derived> at all.-Darin
On Jul 16, 2012 2:25 PM, "Albert J. Wong (王重傑)" <ajw...@chromium.org> wrote:
Interesting problem...I'd be hesitant about introducing an API that encourages downcasting. My first reaction is to ask whether or not implementation inheritance can be avoided. For example, you could add protected manually implementedvirtual WeakPtr<Base> AsWeak() = 0;and have your derived classes provide the backing WeakPtrFactory.
Thanks for all your input. Let me try to summarize: People feel that a generic WeakPtr casting facility could be useful, and we'd likely just add it to WeakPtr. It would perform unsafe casts and it's up to the caller to make sure their casts are valid. There's some valid concern though regarding WeakPtr<Derived> only being invalidated after the Derived dtor completes. Open question: Is that concern strong enough to abandon the idea?Some thoughts...
1- On one hand, casting between WeakPtr<A> and WeakPtr<B> shouldn't need to be anymore restrictive than static_cast'ing between A* and B*. WeakPtr is just a container for a raw pointer. The only thing it adds is a way to null out the raw pointer when the object it points to disappears.I agree to that. My concern is that people are trained to watch out when writing static_casts, but they're probably much less careful when calling a function.2- The concern Wez raised is a good one. What does it mean to have a non-null WeakPtr<Derived> pointing to a Derived object that has already executed ~Derived? That seems like a problematic state.Wez has a valid point. I'm not sure how much of an issue it is in practice though. A WeakPtr can only be used from one thread, so you'll only get into trouble if you have code in the dtors triggering WeakPtr accesses. IMHO that's about the same level of dragons you get with the vtable calls from dtors, and since our guideline seams to be making WeakPtrs behave as similar to raw pointers as possible, I'm not that concerned.#1 is what encouraged me to suggest WeakPtr<T>::From(const WeakPtr<U>&), but #2 makes me think we shouldn't support down-casting WeakPtr<Base> to WeakPtr<Derived> at all.-Darin
On Jul 16, 2012 2:25 PM, "Albert J. Wong (王重傑)" <ajw...@chromium.org> wrote:
Interesting problem...I'd be hesitant about introducing an API that encourages downcasting. My first reaction is to ask whether or not implementation inheritance can be avoided. For example, you could add protected manually implementedvirtual WeakPtr<Base> AsWeak() = 0;and have your derived classes provide the backing WeakPtrFactory.Yes, that would suit my needs, and I'm planning to go with for now.
Thanks for all your input. Let me try to summarize: People feel that a generic WeakPtr casting facility could be useful, and we'd likely just add it to WeakPtr. It would perform unsafe casts and it's up to the caller to make sure their casts are valid. There's some valid concern though regarding WeakPtr<Derived> only being invalidated after the Derived dtor completes. Open question: Is that concern strong enough to abandon the idea?Some thoughts...
1- On one hand, casting between WeakPtr<A> and WeakPtr<B> shouldn't need to be anymore restrictive than static_cast'ing between A* and B*. WeakPtr is just a container for a raw pointer. The only thing it adds is a way to null out the raw pointer when the object it points to disappears.I agree to that. My concern is that people are trained to watch out when writing static_casts, but they're probably much less careful when calling a function.2- The concern Wez raised is a good one. What does it mean to have a non-null WeakPtr<Derived> pointing to a Derived object that has already executed ~Derived? That seems like a problematic state.Wez has a valid point. I'm not sure how much of an issue it is in practice though. A WeakPtr can only be used from one thread, so you'll only get into trouble if you have code in the dtors triggering WeakPtr accesses. IMHO that's about the same level of dragons you get with the vtable calls from dtors, and since our guideline seams to be making WeakPtrs behave as similar to raw pointers as possible, I'm not that concerned.
Good point. Hmm... maybe SupportsWeakPtr is bad.
Good point. Hmm... maybe SupportsWeakPtr is bad.