C++: Use shared_from_this() exclusively on this

Never call shared_from_this() on any object other than "this".
Adapt the API so that it can be made protected.
This commit is contained in:
Daniel Elstner 2015-10-11 17:01:05 +02:00
parent 21d1bec60e
commit 67b82fc9c9
2 changed files with 40 additions and 41 deletions

View File

@ -159,7 +159,7 @@ map<string, shared_ptr<Driver>> Context::drivers()
{ {
auto name = entry.first; auto name = entry.first;
auto driver = entry.second; auto driver = entry.second;
result[name] = driver->get_shared_pointer(this); result[name] = driver->get_shared_pointer(shared_from_this());
} }
return result; return result;
} }
@ -171,7 +171,7 @@ map<string, shared_ptr<InputFormat>> Context::input_formats()
{ {
auto name = entry.first; auto name = entry.first;
auto input_format = entry.second; auto input_format = entry.second;
result[name] = input_format->get_shared_pointer(this); result[name] = input_format->get_shared_pointer(shared_from_this());
} }
return result; return result;
} }
@ -183,7 +183,7 @@ map<string, shared_ptr<OutputFormat>> Context::output_formats()
{ {
auto name = entry.first; auto name = entry.first;
auto output_format = entry.second; auto output_format = entry.second;
result[name] = output_format->get_shared_pointer(this); result[name] = output_format->get_shared_pointer(shared_from_this());
} }
return result; return result;
} }
@ -779,7 +779,7 @@ vector<shared_ptr<TriggerStage>> Trigger::stages()
{ {
vector<shared_ptr<TriggerStage>> result; vector<shared_ptr<TriggerStage>> result;
for (auto stage : _stages) for (auto stage : _stages)
result.push_back(stage->get_shared_pointer(this)); result.push_back(stage->get_shared_pointer(shared_from_this()));
return result; return result;
} }
@ -787,7 +787,7 @@ shared_ptr<TriggerStage> Trigger::add_stage()
{ {
auto stage = new TriggerStage(sr_trigger_stage_add(_structure)); auto stage = new TriggerStage(sr_trigger_stage_add(_structure));
_stages.push_back(stage); _stages.push_back(stage);
return stage->get_shared_pointer(this); return stage->get_shared_pointer(shared_from_this());
} }
TriggerStage::TriggerStage(struct sr_trigger_stage *structure) : TriggerStage::TriggerStage(struct sr_trigger_stage *structure) :
@ -810,7 +810,7 @@ vector<shared_ptr<TriggerMatch>> TriggerStage::matches()
{ {
vector<shared_ptr<TriggerMatch>> result; vector<shared_ptr<TriggerMatch>> result;
for (auto match : _matches) for (auto match : _matches)
result.push_back(match->get_shared_pointer(this)); result.push_back(match->get_shared_pointer(shared_from_this()));
return result; return result;
} }
@ -925,7 +925,7 @@ shared_ptr<Device> Session::get_device(const struct sr_dev_inst *sdi)
{ {
if (_owned_devices.count(sdi)) if (_owned_devices.count(sdi))
return static_pointer_cast<Device>( return static_pointer_cast<Device>(
_owned_devices[sdi]->get_shared_pointer(this)); _owned_devices[sdi]->get_shared_pointer(shared_from_this()));
else if (_other_devices.count(sdi)) else if (_other_devices.count(sdi))
return _other_devices[sdi]; return _other_devices[sdi];
else else
@ -1092,7 +1092,7 @@ const PacketType *Packet::type() const
shared_ptr<PacketPayload> Packet::payload() shared_ptr<PacketPayload> Packet::payload()
{ {
if (_payload) if (_payload)
return _payload->get_shared_pointer(this); return _payload->get_shared_pointer(shared_from_this());
else else
throw Error(SR_ERR_NA); throw Error(SR_ERR_NA);
} }
@ -1115,7 +1115,7 @@ Header::~Header()
{ {
} }
shared_ptr<PacketPayload> Header::get_shared_pointer(Packet *_parent) shared_ptr<PacketPayload> Header::get_shared_pointer(shared_ptr<Packet> _parent)
{ {
return static_pointer_cast<PacketPayload>( return static_pointer_cast<PacketPayload>(
ParentOwned::get_shared_pointer(_parent)); ParentOwned::get_shared_pointer(_parent));
@ -1143,7 +1143,7 @@ Meta::~Meta()
{ {
} }
shared_ptr<PacketPayload> Meta::get_shared_pointer(Packet *_parent) shared_ptr<PacketPayload> Meta::get_shared_pointer(shared_ptr<Packet> _parent)
{ {
return static_pointer_cast<PacketPayload>( return static_pointer_cast<PacketPayload>(
ParentOwned::get_shared_pointer(_parent)); ParentOwned::get_shared_pointer(_parent));
@ -1169,7 +1169,7 @@ Logic::~Logic()
{ {
} }
shared_ptr<PacketPayload> Logic::get_shared_pointer(Packet *_parent) shared_ptr<PacketPayload> Logic::get_shared_pointer(shared_ptr<Packet> _parent)
{ {
return static_pointer_cast<PacketPayload>( return static_pointer_cast<PacketPayload>(
ParentOwned::get_shared_pointer(_parent)); ParentOwned::get_shared_pointer(_parent));
@ -1200,7 +1200,7 @@ Analog::~Analog()
{ {
} }
shared_ptr<PacketPayload> Analog::get_shared_pointer(Packet *_parent) shared_ptr<PacketPayload> Analog::get_shared_pointer(shared_ptr<Packet> _parent)
{ {
return static_pointer_cast<PacketPayload>( return static_pointer_cast<PacketPayload>(
ParentOwned::get_shared_pointer(_parent)); ParentOwned::get_shared_pointer(_parent));
@ -1290,8 +1290,7 @@ shared_ptr<Input> InputFormat::create_input(
auto input = sr_input_new(_structure, map_to_hash_variant(options)); auto input = sr_input_new(_structure, map_to_hash_variant(options));
if (!input) if (!input)
throw Error(SR_ERR_ARG); throw Error(SR_ERR_ARG);
return shared_ptr<Input>( return shared_ptr<Input>(new Input(_parent, input), Input::Deleter());
new Input(_parent->shared_from_this(), input), Input::Deleter());
} }
Input::Input(shared_ptr<Context> context, const struct sr_input *structure) : Input::Input(shared_ptr<Context> context, const struct sr_input *structure) :

View File

@ -164,21 +164,14 @@ protected:
{ {
} }
public:
/* Get parent object that owns this object. */
shared_ptr<Parent> parent()
{
return _parent;
}
/* Note, this implementation will create a new smart_ptr if none exists. */ /* Note, this implementation will create a new smart_ptr if none exists. */
shared_ptr<Class> shared_from_this() shared_ptr<Class> shared_from_this()
{ {
shared_ptr<Class> shared; shared_ptr<Class> shared = _weak_this.lock();
if (!(shared = _weak_this.lock())) if (!shared)
{ {
shared = shared_ptr<Class>(static_cast<Class *>(this), reset_parent); shared.reset(static_cast<Class *>(this), &reset_parent);
_weak_this = shared; _weak_this = shared;
} }
@ -193,11 +186,11 @@ public:
return shared_from_this(); return shared_from_this();
} }
shared_ptr<Class> get_shared_pointer(Parent *parent) public:
/* Get parent object that owns this object. */
shared_ptr<Parent> parent()
{ {
if (!parent) return _parent;
throw Error(SR_ERR_BUG);
return get_shared_pointer(parent->shared_from_this());
} }
}; };
@ -205,14 +198,6 @@ public:
template <class Class, typename Struct> template <class Class, typename Struct>
class SR_API UserOwned : public enable_shared_from_this<Class> class SR_API UserOwned : public enable_shared_from_this<Class>
{ {
public:
shared_ptr<Class> shared_from_this()
{
auto shared = enable_shared_from_this<Class>::shared_from_this();
if (!shared)
throw Error(SR_ERR_BUG);
return shared;
}
protected: protected:
Struct *_structure; Struct *_structure;
@ -221,6 +206,14 @@ protected:
{ {
} }
shared_ptr<Class> shared_from_this()
{
auto shared = enable_shared_from_this<Class>::shared_from_this();
if (!shared)
throw Error(SR_ERR_BUG);
return shared;
}
/* Deleter needed to allow shared_ptr use with protected destructor. */ /* Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter class Deleter
{ {
@ -714,8 +707,15 @@ class SR_API PacketPayload
protected: protected:
PacketPayload(); PacketPayload();
virtual ~PacketPayload() = 0; virtual ~PacketPayload() = 0;
virtual shared_ptr<PacketPayload> get_shared_pointer(Packet *parent) = 0; private:
virtual shared_ptr<PacketPayload> get_shared_pointer(shared_ptr<Packet> parent) = 0;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(PacketPayload *payload) { delete payload; }
};
friend class Deleter; friend class Deleter;
friend class Packet; friend class Packet;
friend class Output; friend class Output;
@ -734,7 +734,7 @@ public:
private: private:
explicit Header(const struct sr_datafeed_header *structure); explicit Header(const struct sr_datafeed_header *structure);
~Header(); ~Header();
shared_ptr<PacketPayload> get_shared_pointer(Packet *parent); shared_ptr<PacketPayload> get_shared_pointer(shared_ptr<Packet> parent);
friend class Packet; friend class Packet;
}; };
@ -749,7 +749,7 @@ public:
private: private:
explicit Meta(const struct sr_datafeed_meta *structure); explicit Meta(const struct sr_datafeed_meta *structure);
~Meta(); ~Meta();
shared_ptr<PacketPayload> get_shared_pointer(Packet *parent); shared_ptr<PacketPayload> get_shared_pointer(shared_ptr<Packet> parent);
map<const ConfigKey *, Glib::VariantBase> _config; map<const ConfigKey *, Glib::VariantBase> _config;
friend class Packet; friend class Packet;
}; };
@ -769,7 +769,7 @@ public:
private: private:
explicit Logic(const struct sr_datafeed_logic *structure); explicit Logic(const struct sr_datafeed_logic *structure);
~Logic(); ~Logic();
shared_ptr<PacketPayload> get_shared_pointer(Packet *parent); shared_ptr<PacketPayload> get_shared_pointer(shared_ptr<Packet> parent);
friend class Packet; friend class Packet;
}; };
@ -794,7 +794,7 @@ public:
private: private:
explicit Analog(const struct sr_datafeed_analog *structure); explicit Analog(const struct sr_datafeed_analog *structure);
~Analog(); ~Analog();
shared_ptr<PacketPayload> get_shared_pointer(Packet *parent); shared_ptr<PacketPayload> get_shared_pointer(shared_ptr<Packet> parent);
friend class Packet; friend class Packet;
}; };