Call correct destructor in base::Observable.

base::Subscription::Node doesn't have a virtual destructor.
This commit is contained in:
John Preston 2017-08-13 18:52:31 +03:00
parent 71e0e6ac4d
commit 95af8da66a
1 changed files with 9 additions and 10 deletions

View File

@ -62,11 +62,11 @@ public:
Subscription() = default; Subscription() = default;
Subscription(const Subscription &) = delete; Subscription(const Subscription &) = delete;
Subscription &operator=(const Subscription &) = delete; Subscription &operator=(const Subscription &) = delete;
Subscription(Subscription &&other) : _node(base::take(other._node)), _removeMethod(other._removeMethod) { Subscription(Subscription &&other) : _node(base::take(other._node)), _removeAndDestroyMethod(other._removeAndDestroyMethod) {
} }
Subscription &operator=(Subscription &&other) { Subscription &operator=(Subscription &&other) {
qSwap(_node, other._node); qSwap(_node, other._node);
qSwap(_removeMethod, other._removeMethod); qSwap(_removeAndDestroyMethod, other._removeAndDestroyMethod);
return *this; return *this;
} }
explicit operator bool() const { explicit operator bool() const {
@ -74,9 +74,7 @@ public:
} }
void destroy() { void destroy() {
if (_node) { if (_node) {
(*_removeMethod)(_node); (*_removeAndDestroyMethod)(base::take(_node));
delete _node;
_node = nullptr;
} }
} }
~Subscription() { ~Subscription() {
@ -91,12 +89,12 @@ private:
Node *prev = nullptr; Node *prev = nullptr;
QWeakPointer<internal::BaseObservableData> observable; QWeakPointer<internal::BaseObservableData> observable;
}; };
using RemoveMethod = void(*)(Node*); using RemoveAndDestroyMethod = void(*)(Node*);
Subscription(Node *node, RemoveMethod removeMethod) : _node(node), _removeMethod(removeMethod) { Subscription(Node *node, RemoveAndDestroyMethod removeAndDestroyMethod) : _node(node), _removeAndDestroyMethod(removeAndDestroyMethod) {
} }
Node *_node = nullptr; Node *_node = nullptr;
RemoveMethod _removeMethod; RemoveAndDestroyMethod _removeAndDestroyMethod;
template <typename EventType, typename Handler> template <typename EventType, typename Handler>
friend class internal::CommonObservableData; friend class internal::CommonObservableData;
@ -176,7 +174,7 @@ public:
} else { } else {
_begin = _end = node; _begin = _end = node;
} }
return { _end, &CommonObservableData::destroyNode }; return { _end, &CommonObservableData::removeAndDestroyNode };
} }
bool empty() const { bool empty() const {
@ -210,10 +208,11 @@ private:
} }
} }
static void destroyNode(Subscription::Node *node) { static void removeAndDestroyNode(Subscription::Node *node) {
if (auto that = node->observable.toStrongRef()) { if (auto that = node->observable.toStrongRef()) {
static_cast<CommonObservableData*>(that.data())->remove(node); static_cast<CommonObservableData*>(that.data())->remove(node);
} }
delete static_cast<Node*>(node);
} }
template <typename CallCurrent> template <typename CallCurrent>