Re: What kind of pattern is this?
On Nov 9, 2:54 pm, Marcel M=FCller <news.5.ma...@spamgourmet.org> wrote:
I have a class that destroys itself after it has done its job. Something
like a thread, but without a thread.
// Some Object
class MyObject;
// Schedule a task for obj in the Worker Queue.
void ScheduleObject(MyObject* obj);
class RescheduleWorker
{private:
intrusive_ptr<MyObject> Object;
vector<intrusive_ptr<MyObject> > Dependencies;
public:
RescheduleWorker(MyObject& obj,
const vector<intrusive_ptr<MyObject> >& dependencies)
: Object(&obj), Dependencies(dependencies)
{ // register some callbacks in the dependency list
}
private:
~RescheduleWorker() {}
// Called by some internal observer functions exactly once
// when a complex dependency condition is true.
void OnCompleted()
{ ScheduleObject(Object.get());
delete this;
}
};
Constructors and destructors ignore how the object's bit bucket was
allocated, so if you are restricting methods of deletion, then you
must restrict methods of creation so others don't allocate
recklessly. I also threw in a way of listing the dependencies
directly, without having to make a std::vector first.
// I've never used C++11 myself, mostly guessing
class Rescheduleworker
{
public:
template <typename... Args>
static void create_and_attach( MyObject &main_object, Args...
&objects )
{
std::unique_ptr<Rescheduleworker> w{ new
Rescheduleworker{main_object, objects} };
// Any other code goes here. Only if there isn't any you can
// replace the entire function with a single "new
// Rescheduleworker{main_objects, objects}" line. The way I
// have it here makes it safe if the other code throws.
w.release();
}
private:
using ObjectPtr = intrusive_ptr<MyObject>;
ObjectPtr Object;
std::vector<ObjectPtr> Dependencies;
FillDependencies()
{}
template <typename... Args>
FillDependencies( MyObject &dependency, Args... &dependencies )
{
this->Dependencies.push_back( &dependency );
this->FillDependencies( dependencies );
}
template <typename... Args>
Rescheduleworker( MyObject &obj, Args... &dependencies )
: Object{ &obj }, Dependencies{}
{
this->Dependencies.reserve( sizeof...(dependencies) );
this->FillDependencies( dependencies );
// Put any other setup here.
// Your code may vary; but something like this must be set up,
// where the completion routine will be called, which
// deallocates this object.
Something( obj ).SetSomeMethod( std::bind(this,
&Rescheduleworker::OnCompleted) );
}
~Rescheduleworker() = default;
void OnCompleted()
{
ScheduleObject( this->Object.get() );
delete this;
}
};
// usage:
new RescheduleWorker(obj, dependencies);
// Now:
// (Of course, now it does NOT work if you already have the
dependencies in
// a vector or other container. We would need another
"create_and_attach"
// and constructor (template) overloads for vectors (and/or
iterators).)
Rescheduleworker::create_and_attach( obj, dependency1, ...,
dependencyN );
The latter looks a bit strange, because the pointer returned by new is
immediately discarded. Is this a common pattern? How is it called?
This seems to be a variant of the factory pattern, except that the
returned pointer is never used.
Daryle W.