Skip to content

Commit a460965

Browse files
author
Kjell Ahlstedt
committed
slot_rep: Make destructor, destroy() and dup() virtual
* sigc++/functors/slot_base.h: * sigc++/functors/slot.h: Make ~slot_rep(), slot_rep::destroy() and slot_rep::dup() virtual. Bug 777618
1 parent 714caf1 commit a460965

File tree

2 files changed

+19
-46
lines changed

2 files changed

+19
-46
lines changed

sigc++/functors/slot.h

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ template <typename T_functor>
4343
struct typed_slot_rep : public slot_rep
4444
{
4545
private:
46-
using self = typed_slot_rep<T_functor>;
47-
4846
/* Use an adaptor type so that arguments can be passed as const references
4947
* through explicit template instantiation from slot_call#::call_it() */
5048
using adaptor_type = typename adaptor_trait<T_functor>::adaptor_type;
@@ -58,13 +56,13 @@ struct typed_slot_rep : public slot_rep
5856
* @param functor The functor contained by the new slot_rep object.
5957
*/
6058
inline explicit typed_slot_rep(const T_functor& functor)
61-
: slot_rep(nullptr, &destroy, &dup), functor_(std::make_unique<adaptor_type>(functor))
59+
: slot_rep(nullptr), functor_(std::make_unique<adaptor_type>(functor))
6260
{
6361
sigc::visit_each_trackable(slot_do_bind(this), *functor_);
6462
}
6563

6664
inline typed_slot_rep(const typed_slot_rep& src)
67-
: slot_rep(src.call_, &destroy, &dup), functor_(std::make_unique<adaptor_type>(*src.functor_))
65+
: slot_rep(src.call_), functor_(std::make_unique<adaptor_type>(*src.functor_))
6866
{
6967
sigc::visit_each_trackable(slot_do_bind(this), *functor_);
7068
}
@@ -74,24 +72,25 @@ struct typed_slot_rep : public slot_rep
7472
typed_slot_rep(typed_slot_rep&& src) = delete;
7573
typed_slot_rep& operator=(typed_slot_rep&& src) = delete;
7674

77-
inline ~typed_slot_rep()
75+
~typed_slot_rep() override
7876
{
79-
call_ = nullptr;
80-
destroy_ = nullptr;
81-
sigc::visit_each_trackable(slot_do_unbind(this), *functor_);
77+
// Call destroy() non-virtually.
78+
// It's unwise to make virtual calls in a constructor or destructor.
79+
typed_slot_rep::destroy();
8280
}
8381

8482
private:
8583
/** Detaches the stored functor from the other referred trackables and destroys it.
8684
* This does not destroy the base slot_rep object.
8785
*/
88-
static void destroy(slot_rep* data)
86+
void destroy() override
8987
{
90-
auto self_ = static_cast<self*>(data);
91-
self_->call_ = nullptr;
92-
self_->destroy_ = nullptr;
93-
sigc::visit_each_trackable(slot_do_unbind(self_), *self_->functor_);
94-
self_->functor_.reset(nullptr);
88+
call_ = nullptr;
89+
if (functor_)
90+
{
91+
sigc::visit_each_trackable(slot_do_unbind(this), *functor_);
92+
functor_.reset(nullptr);
93+
}
9594
/* don't call disconnect() here: destroy() is either called
9695
* a) from the parent itself (in which case disconnect() leads to a segfault) or
9796
* b) from a parentless slot (in which case disconnect() does nothing)
@@ -103,7 +102,7 @@ struct typed_slot_rep : public slot_rep
103102
* slot_rep object is registered in the referred trackables.
104103
* @return A deep copy of the slot_rep object.
105104
*/
106-
static slot_rep* dup(slot_rep* a_rep) { return new self(*static_cast<self*>(a_rep)); }
105+
slot_rep* dup() const override { return new typed_slot_rep(*this); }
107106
};
108107

109108
/** Abstracts functor execution.

sigc++/functors/slot_base.h

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,14 @@ struct SIGC_API slot_rep : public trackable
6666
* down dereferencing of slot list iterators. Martin. */
6767
// TODO: Try this now? murrayc.
6868

69-
using hook_dup = slot_rep* (*)(slot_rep*);
70-
71-
using func_slot_rep_destroy_notify = void (*)(slot_rep* data);
72-
73-
inline slot_rep(hook call__, func_slot_rep_destroy_notify destroy__, hook_dup dup__) noexcept
69+
inline slot_rep(hook call__) noexcept
7470
: call_(call__),
7571
cleanup_(nullptr),
76-
parent_(nullptr),
77-
destroy_(destroy__),
78-
dup_(dup__)
72+
parent_(nullptr)
7973
{
8074
}
8175

82-
inline ~slot_rep() { destroy(); }
76+
virtual ~slot_rep() {}
8377

8478
// only MSVC needs this to guarantee that all new/delete are executed from the DLL module
8579
#ifdef SIGC_NEW_DELETE_IN_LIBRARY_ONLY
@@ -89,19 +83,12 @@ struct SIGC_API slot_rep : public trackable
8983

9084
/** Destroys the slot_rep object (but doesn't delete it).
9185
*/
92-
inline void destroy()
93-
{
94-
if (destroy_)
95-
(*destroy_)(this);
96-
}
86+
virtual void destroy() = 0;
9787

9888
/** Makes a deep copy of the slot_rep object.
9989
* @return A deep copy of the slot_rep object.
10090
*/
101-
inline slot_rep* dup() const
102-
{
103-
return (*dup_)(const_cast<slot_rep*>(this));
104-
}
91+
virtual slot_rep* dup() const = 0;
10592

10693
/** Set the parent with a callback.
10794
* slots have one parent exclusively.
@@ -148,19 +135,6 @@ struct SIGC_API slot_rep : public trackable
148135

149136
/** Parent object whose callback cleanup_ is executed on notification. */
150137
notifiable* parent_;
151-
152-
protected:
153-
/// Callback that detaches the slot_rep object from referred trackables and destroys it.
154-
/* This could be a replaced by a virtual dtor. However, since this struct is
155-
* crucial for the efficiency of the whole library, we want to avoid this.
156-
*/
157-
func_slot_rep_destroy_notify destroy_;
158-
159-
private:
160-
/** Callback that makes a deep copy of the slot_rep object.
161-
* @return A deep copy of the slot_rep object.
162-
*/
163-
hook_dup dup_;
164138
};
165139

166140
/** Functor used to add a dependency to a trackable.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy