I have an object -a scheduler class-. This scheduler class is given member function pointers, times and the pointer to the object which created the scheduler.
This means I could do something as much as: (pObject->*h.function)(*h.param); Where pObject is the pointer to the original object, h a class which contains the function + void pointer parameter so I can pass arguments to the original function.
When I like to initialize this object I have the explicit Scheduler(pObjType o); constructor (where pObjType is a template parameter).
When I create an object which should have this alarm I type:
struct A {
typedef void (A::*A_FN2)(void*);
typedef Scheduler<A*,A_FN2> AlarmType;
A(int _x) : alarm(NULL)
{
alarm.SetObject(this);
}
AlarmType alarm
However this alarm-type puts quite a big limitation on the object: if I forget to add a copy-constructor (to A) the class would get undefined behaviour. The scheduler would keep pointing to the original object, and that original object might go out of scope, or even worse, might not.
Is there a method that when I copy my alarm (by default, so in the scheduler's copy-constructor) I can get the calling object (and pointer to that?)?
Or if that isn't possible, is it possible to throw a (compile) error if I forget to implement a copy-constructor for my structure? - And try to copy this structure somewhere?
As I see it, you have an opportunity to improve your design here, that may help you get rid of your worry.
It is usually a bad idea to pass
around member function pointers. It
is better to make your structs
inherit from an abstract base class,
making the functions you want to
customize abstract virtual.
If you don't need copying, it is best
to disallow it in the base class.
Either by making the copy constructor and operator undefined and private,
or by inheriting boost::NonCopyable.
If you want any kind of automatic copy construction semantics, then you're going to need to go to the CRTP- no other pattern provides for a pointer to the owning object.
The other thing is that you should really use a boost::/std::function<>, they're far more generic and you're going to need that if you want to be able to use Lua functions.
The simplest way to prevent the specific issue you're asking about is to make Scheduler noncopyable (e.g. with boost::noncopyable). This means that any client class incorporating a value member of type Scheduler will fail to be copyable. The hope is that this provides a hint for the programmer to check the docs and figure out the copy semantics of Scheduler (i.e. construct a new Scheduler for every new A), but it's possible for someone to get this wrong if they work around the problem by just holding the Scheduler by pointer. Aliasing the pointer gives exactly the same problem as default-copy-constructing the Scheduler instance that holds a pointer.
Any time you have raw pointers you have to have a policy on object lifetime. You want to ensure that the lifetime of any class A is at least as long as the corresponding instance of Scheduler, and as I see it there are three ways to ensure this:
Use composition - not possible in this case because A contains a Scheduler, so Scheduler can't contain an A
Use inheritance, e.g. in the form of the Curiously Recurring Template Pattern (CRTP)
Have a global policy on enforcing lifetimes of A instances, e.g. requiring that they are always held by smart pointer, or that cleaning them up is the responsibility of some class that also knows to clean up the Schedulers that depend on them
The CRTP could work like this:
#include <iostream>
using namespace std;
template<typename T>
struct Scheduler {
typedef void (T::* MemFuncPtr)(void);
Scheduler(MemFuncPtr action) :
action(action)
{
}
private:
void doAction()
{
this->*action();
}
MemFuncPtr action;
};
struct Alarm : private Scheduler<Alarm> {
Alarm() : Scheduler<Alarm>(&Alarm::doStuff)
{
}
void doStuff()
{
cout << "Doing stuff" << endl;
}
};
Note that private inheritance ensures that clients of the Alarm class can't treat it as a raw Scheduler.
Related
I am using a factory to create some objects at runtime based on some user selections.
So I have something like this currently:
class UpdateServiceFactory{
public:
std::unique_ptr<UpdateService> create(Widget widget){
if(widget.name == "name one"){
auto dependency = std::make_unique<ChildDependency>();
return std::make_unique<ChildUpdateService>(std::move(dep));
}
}
}
My ChildUpdateService can:
a) take a unique pointer to its dependency. On one hand, this seems ideal, because I want my dependency to go out of scope when my UpdateService is destroyed. But on the other hand, I am now forcing a lifetime policy on the creator of the object from an object that shouldn't really care about it, just for the sake of easy cleanup of the memory. For example, my ChildUpdateService has no idea if the factory wants to pass the same dependency it just created to another class as well, which a unique pointer would make impossible. And it seems I've now dictated that by specifying the smart pointer on my constructor.
b) I could take a raw dependency pointer into the constructor of the ChildUpdateService and pass it using unique_ptr::get. But now I have the issue of needing to manage the lifetime of the dependency pointer elsewhere. Something has to own it otherwise it's going to go out of scope as soon as the create function returns. At this point, the only object that knows about the pointer is my factory, but the factory shouldn't really be responsible for managing the pointer's lifetime either. Its job is to create the object and that's it. I feel like doing any more would be a violation of the SRP.
So my question is two fold, I suppose. 1) If a constructor takes a unique pointer, am I dictating a lifetime policy on the creator of the object that I shouldn't be? And 2) is there a pattern that solves this problem which I could (should) use, such as creating an intermediate object, whose job is to manage the lifetime of the dependency?
If you want your Service type to decide this, then you require its assistance when creating the Dependency. You could do it like this:
class ServiceBase { // you need this anyway
public:
virtual ~ServiceBase() {}
};
class ChildUpdateService : public ServiceBase {
private:
// now, the class itself defines that it wants to store a unique_ptr.
// not the generic factory!
ChildUpdateService(std::unique_ptr<ChildDependency>);
public:
template <typename Dep, typename... Args>
static std::unique_ptr<ChildUpdateService> make(Args&&... args) {
return std::make_unique<ChildUpdateService>(std::make_unique<T>(std::forward<Args>(args)...));
}
};
If you have several Services like this, maybe create an intermediary class template that employs CRTP.
This means that your generic factory doesn't have to decide how the respective Service implementation keeps its dependency around (as unique_ptr, as shared_ptr, as automatic member, etc.).
class UpdateServiceFactory {
public:
std::unique_ptr<UpdateService> create(Widget widget) {
if (widget.name == "name one")
return ChildUpdateService::make<ChildDependency>();
}
}
I've been thinking about the possible use of delete this in c++, and I've seen one use.
Because you can say delete this only when an object is on heap, I can make the destructor private and stop objects from being created on stack altogether. In the end I can just delete the object on heap by saying delete this in a random public member function that acts as a destructor. My questions:
1) Why would I want to force the object to be made on the heap instead of on the stack?
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Any scheme that uses delete this is somewhat dangerous, since whoever called the function that does that is left with a dangling pointer. (Of course, that's also the case when you delete an object normally, but in that case, it's clear that the object has been deleted). Nevertheless, there are somewhat legitimate cases for wanting an object to manage its own lifetime.
It could be used to implement a nasty, intrusive reference-counting scheme. You would have functions to "acquire" a reference to the object, preventing it from being deleted, and then "release" it once you've finished, deleting it if noone else has acquired it, along the lines of:
class Nasty {
public:
Nasty() : references(1) {}
void acquire() {
++references;
}
void release() {
if (--references == 0) {
delete this;
}
}
private:
~Nasty() {}
size_t references;
};
// Usage
Nasty * nasty = new Nasty; // 1 reference
nasty->acquire(); // get a second reference
nasty->release(); // back to one
nasty->release(); // deleted
nasty->acquire(); // BOOM!
I would prefer to use std::shared_ptr for this purpose, since it's thread-safe, exception-safe, works for any type without needing any explicit support, and prevents access after deleting.
More usefully, it could be used in an event-driven system, where objects are created, and then manage themselves until they receive an event that tells them that they're no longer needed:
class Worker : EventReceiver {
public:
Worker() {
start_receiving_events(this);
}
virtual void on(WorkEvent) {
do_work();
}
virtual void on(DeleteEvent) {
stop_receiving_events(this);
delete this;
}
private:
~Worker() {}
void do_work();
};
1) Why would I want to force the object to be made on the heap instead of on the stack?
1) Because the object's lifetime is not logically tied to a scope (e.g., function body, etc.). Either because it must manage its own lifespan, or because it is inherently a shared object (and thus, its lifespan must be attached to those of its co-dependent objects). Some people here have pointed out some examples like event handlers, task objects (in a scheduler), and just general objects in a complex object hierarchy.
2) Because you want to control the exact location where code is executed for the allocation / deallocation and construction / destruction. The typical use-case here is that of cross-module code (spread across executables and DLLs (or .so files)). Because of issues of binary compatibility and separate heaps between modules, it is often a requirement that you strictly control in what module these allocation-construction operations happen. And that implies the use of heap-based objects only.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Well, your use-case is really just a "how-to" not a "why". Of course, if you are going to use a delete this; statement within a member function, then you must have controls in place to force all creations to occur with new (and in the same translation unit as the delete this; statement occurs). Not doing this would just be very very poor style and dangerous. But that doesn't address the "why" you would use this.
1) As others have pointed out, one legitimate use-case is where you have an object that can determine when its job is over and consequently destroy itself. For example, an event handler deleting itself when the event has been handled, a network communication object that deletes itself once the transaction it was appointed to do is over, or a task object in a scheduler deleting itself when the task is done. However, this leaves a big problem: signaling to the outside world that it no longer exists. That's why many have mentioned the "intrusive reference counting" scheme, which is one way to ensure that the object is only deleted when there are no more references to it. Another solution is to use a global (singleton-like) repository of "valid" objects, in which case any accesses to the object must go through a check in the repository and the object must also add/remove itself from the repository at the same time as it makes the new and delete this; calls (either as part of an overloaded new/delete, or alongside every new/delete calls).
However, there is a much simpler and less intrusive way to achieve the same behavior, albeit less economical. One can use a self-referencing shared_ptr scheme. As so:
class AutonomousObject {
private:
std::shared_ptr<AutonomousObject> m_shared_this;
protected:
AutonomousObject(/* some params */);
public:
virtual ~AutonomousObject() { };
template <typename... Args>
static std::weak_ptr<AutonomousObject> Create(Args&&... args) {
std::shared_ptr<AutonomousObject> result(new AutonomousObject(std::forward<Args>(args)...));
result->m_shared_this = result; // link the self-reference.
return result; // return a weak-pointer.
};
// this is the function called when the life-time should be terminated:
void OnTerminate() {
m_shared_this.reset( NULL ); // do not use reset(), but use reset( NULL ).
};
};
With the above (or some variations upon this crude example, depending on your needs), the object will be alive for as long as it deems necessary and that no-one else is using it. The weak-pointer mechanism serves as the proxy to query for the existence of the object, by possible outside users of the object. This scheme makes the object a bit heavier (has a shared-pointer in it) but it is easier and safer to implement. Of course, you have to make sure that the object eventually deletes itself, but that's a given in this kind of scenario.
2) The second use-case I can think of ties in to the second motivation for restricting an object to be heap-only (see above), however, it applies also for when you don't restrict it as such. If you want to make sure that both the deallocation and the destruction are dispatched to the correct module (the module from which the object was allocated and constructed), you must use a dynamic dispatching method. And for that, the easiest is to just use a virtual function. However, a virtual destructor is not going to cut it because it only dispatches the destruction, not the deallocation. The solution is to use a virtual "destroy" function that calls delete this; on the object in question. Here is a simple scheme to achieve this:
struct CrossModuleDeleter; //forward-declare.
class CrossModuleObject {
private:
virtual void Destroy() /* final */;
public:
CrossModuleObject(/* some params */); //constructor can be public.
virtual ~CrossModuleObject() { }; //destructor can be public.
//.... whatever...
friend struct CrossModuleDeleter;
template <typename... Args>
static std::shared_ptr< CrossModuleObject > Create(Args&&... args);
};
struct CrossModuleDeleter {
void operator()(CrossModuleObject* p) const {
p->Destroy(); // do a virtual dispatch to reach the correct deallocator.
};
};
// In the cpp file:
// Note: This function should not be inlined, so stash it into a cpp file.
void CrossModuleObject::Destroy() {
delete this;
};
template <typename... Args>
std::shared_ptr< CrossModuleObject > CrossModuleObject::Create(Args&&... args) {
return std::shared_ptr< CrossModuleObject >( new CrossModuleObject(std::forward<Args>(args)...), CrossModuleDeleter() );
};
The above kind of scheme works well in practice, and it has the nice advantage that the class can act as a base-class with no additional intrusion by this virtual-destroy mechanism in the derived classes. And, you can also modify it for the purpose of allowing only heap-based objects (as usually, making constructors-destructors private or protected). Without the heap-based restriction, the advantage is that you can still use the object as a local variable or data member (by value) if you want, but, of course, there will be loop-holes left to avoid by whoever uses the class.
As far as I know, these are the only legitimate use-cases I have ever seen anywhere or heard of (and the first one is easily avoidable, as I have shown, and often should be).
The general reason is that the lifetime of the object is determined by some factor internal to the class, at least from an application viewpoint. Hence, it may very well be a private method which calls delete this;.
Obviously, when the object is the only one to know how long it's needed, you can't put it on a random thread stack. It's necessary to create such objects on the heap.
It's generally an exceptionally bad idea. There are a very few cases- for example, COM objects have enforced intrusive reference counting. You'd only ever do this with a very specific situational reason- never for a general-purpose class.
1) Why would I want to force the object to be made on the heap instead of on the stack?
Because its life span isn't determined by the scoping rule.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
You use delete this when the object is the best placed one to be responsible for its own life span. One of the simplest example I know of is a window in a GUI. The window reacts to events, a subset of which means that the window has to be closed and thus deleted. In the event handler the window does a delete this. (You may delegate the handling to a controller class. But the situation "window forwards event to controller class which decides to delete the window" isn't much different of delete this, the window event handler will be left with the window deleted. You may also need to decouple the close from the delete, but your rationale won't be related to the desirability of delete this).
delete this;
can be useful at times and is usually used for a control class that also controls the lifetime of another object. With intrusive reference counting, the class it is controlling is one that derives from it.
The outcome of using such a class should be to make lifetime handling easier for users or creators of your class. If it doesn't achieve this, it is bad practice.
A legitimate example may be where you need a class to clean up all references to itself before it is destructed. In such a case, you "tell" the class whenever you are storing a reference to it (in your model, presumably) and then on exit, your class goes around nulling out these references or whatever before it calls delete this on itself.
This should all happen "behind the scenes" for users of your class.
"Why would I want to force the object to be made on the heap instead of on the stack?"
Generally when you force that it's not because you want to as such, it's because the class is part of some polymorphic hierarchy, and the only legitimate way to get one is from a factory function that returns an instance of a different derived class according to the parameters you pass it, or according to some configuration that it knows about. Then it's easy to arrange that the factory function creates them with new. There's no way that users of those classes could have them on the stack even if they wanted to, because they don't know in advance the derived type of the object they're using, only the base type.
Once you have objects like that, you know that they're destroyed with delete, and you can consider managing their lifecycle in a way that ultimately ends in delete this. You'd only do this if the object is somehow capable of knowing when it's no longer needed, which usually would be (as Mike says) because it's part of some framework that doesn't manage object lifetime explicitly, but does tell its components that they've been detached/deregistered/whatever[*].
If I remember correctly, James Kanze is your man for this. I may have misremembered, but I think he occasionally mentions that in his designs delete this isn't just used but is common. Such designs avoid shared ownership and external lifecycle management, in favour of networks of entity objects managing their own lifecycles. And where necessary, deregistering themselves from anything that knows about them prior to destroying themselves. So if you have several "tools" in a "toolbelt" then you wouldn't construe that as the toolbelt "owning" references to each of the tools, you think of the tools putting themselves in and out of the belt.
[*] Otherwise you'd have your factory return a unique_ptr or auto_ptr to encourage callers to stuff the object straight into the memory management type of their choice, or you'd return a raw pointer but provide the same encouragement via documentation. All the stuff you're used to seeing.
A good rule of thumb is not to use delete this.
Simply put, the thing that uses new should be responsible enough to use the delete when done with the object. This also avoids the problems with is on the stack/heap.
Once upon a time i was writing some plugin code. I believe i mixed build (debug for plugin, release for main code or maybe the other way around) because one part should be fast. Or maybe another situation happened. Such main is already released built on gcc and plugin is being debugged/tested on VC. When the main code deleted something from the plugin or plugin deleted something a memory issue would occur. It was because they both used different memory pools or malloc implementations. So i had a private dtor and a virtual function called deleteThis().
-edit- Now i may consider overloading the delete operator or using a smart pointer or simply just state never delete a function. It will depend and usually overloading new/delete should never be done unless you really know what your doing (dont do it). I decide to use deleteThis() because i found it easier then the C like way of thing_alloc and thing_free as deleteThis() felt like the more OOP way of doing it
I have a function which takes a shared_ptr<MyClass>.
In some member function memfun of MyClass, I need to pass this to that function. But if I write
void MyClass:memfun()
{
func(shared_ptr<MyClass>(this))
}
I am assuming that after the call has ended the reference count will reach 0 and this will be attempted to be destroyed, which is bad.
Then I remembered that there this class enable_shared_from_this with the function shared_from_this.
So now I am going to use the following:
class MyClass: public enable_shared_from_this<MyClass>
{
void MyClass:memfun()
{
func(shared_from_this());
}
};
Questions are:
1) Is is absolutely impossible to use the functionality without deriving from enable_shared_from_this?
2) Does deriving from enable_shared_from_this mean that calling memfun on an object with automatic storage duration will result in something bad? E.g.
int main()
{
MyClass m; //is this OK?
m.memfun(); // what about this?
}
3) If I derive from MyClass, will the enable_shared_from_this functionality be correctly inherited or do I need to derive again? That is,
class MyCoolClass: public Myclass
{
void someCoolMember
{
someCoolFuncTakingSharedPtrToMyCoolClass(shared_from_this());
}
}
Is this OK? Or correct is the following?
class MyCoolClass: public Myclass, public enable_shared_from_this<MyCoolClass>
{
void someCoolMember
{
someCoolFuncTakingSharedPtrToMyCoolClass(enable_shared_from_this<MyCoolClass>::shared_from_this());
}
}
Thanks very much in advance.
1) It depends on what you mean by "do this" as to whether or not you can. You can always construct a shared_ptr from a raw pointer such as this, but it won't share the reference count with another shared_ptr instance that was separately constructed from a raw pointer. You will thus need to use a custom deleter on one or other instance to avoid double deletions, but unless you take great care then you may end up with dangling shared_ptr instances due to the object being deleted through one, but still accessible from another.
shared_from_this enables you to guarantee that if you have one shared_ptr instance to your object then you can construct another without copying the first, and that these instances will share the reference count. You could achieve this by storing a weak_ptr as a class member, and setting that value when you first allocate a shared_ptr to your object.
2) Calling shared_from_this() requires that there is at least one shared_ptr instance already pointing to your object. If you use it on an automatic object without a shared_ptr instance with a custom deleter then you will get bad stuff happening.
3) If you derive from your class then the enable_shared_from_this functionality will give you a shared_ptr to the base class (the one that derived from enable_shared_from_this). You could then use static_pointer_cast or dynamic_pointer_cast to cast the result of shared_from_this() to a pointer to the derived class.
The important question here is why does the function take the argument through a shared_ptr. Does it store the pointer internally for later use? Does it only use it for the duration of the call? Why is the ownership diluted among the caller and the callee?
Some answers suggest that you provide a no-op deleter if you are going to pass a stack allocated object into the function, but if the function is actually storing the shared_ptr for later use, it might be the case that by the time it gets around to it, the locally allocated object is no longer in the stack and you trigger UB. Having the no-op deleter shared_ptr will allow the call, but the semantics will not be correct.
If the function does not store the shared_ptr for later use, what was the design decision that led to that API? If you can change the function (and there is no impending reason), make it receive the argument by reference and you will have a friendlier interface that does not impose a shared_ptr for no reason.
If at the end you determine that you can guarantee that the object in the stack will be alive for the whole duration of the process triggered by that function call, then and only then use the no-op deleter.
1) No, it's not impossible to do this without shared_from_this. You can simply construct a shared_ptr with a no-op deleter:
void do_nothing(MyClass*) {}
void MyClass:memfun()
{
func(shared_ptr<MyClass>(this, do_nothing));
}
Seeing as you don't actually seem to need shared_from_this after all, I'm going to skip the next two parts of your question.
If you have an object with automatic storage and a function that requires shared_ptr and you know that the lifetime of your object will be long enough for the duration of the function and that it does not store the shared_ptr anywhere, then you can pass it with a no-op deleter.
This is useful for static objects. If it really does have local automatic storage, you need to ask yourself why the function is taking shared_ptr. Does it store them?
There is another lesser-known constructor to shared_ptr for an object that is a member of another reference-counted object. You can actually create a shared_ptr with the shared_ptr from the outer object and the pointer from the inner object.
In addition with David RodrÃguez - dribeas, shared pointer isn't recommended by google
It maintains reference count internally, so making it work correctly, InterlockedIncrement and InterlockedDecrement are used, these two functions are really slower than normal ++ and --.
You should check this object ownership truly need be shared with others, per my experience, shared pointer could be avoided in most cases.
At work we have a base class, let's call it IntrusiveBase, that acts something like a mixin to allow a class to be stored in a boost:intrusive_ptr. That is, it provides its subclasses with a ref count and defines intrusive_ptr_add_ref and intrusive_ptr_release overloads. The problem is that it is too easy for someone to forget that a particular subclass inherits from IntrusiveBase, and they then store it in some other smart pointer like a scoped_ptr or shared_ptr. That doesn't work because, for example, the scoped_ptr will delete the object when it goes out of scope no matter what the ref count happens to be. We have an assertion in ~IntrusiveBase that the ref count is one, but this is not foolproof because oftentimes there will end up only being the original instance by the time the scoped_ptr goes out of scope. This leaves an insidious failure waiting to happen those few times that the ref count is not one.
Is there any way that I can cause a compile-time failure if someone accidentally does this? Even if I have to do something repetitively for each of the major smart pointer classes, it would be worth it.
Even if I have to do something repetitively for each of the major smart pointer classes, it would be worth it.
In that case, you can specialize them on your InstrusiveBase inheriting types.
namespace boost
{
template<>
class scoped_ptr<InstrusiveBaseSubclass> { }; // scoped_ptr<InstrusiveBaseSubClass> p(new InstrusiveBaseSubClass) won't compile, neither will p->, p.get() etc.
}
This is annoying but it's macro-able, e..g:
class A : InstrusiveBase
{
...
}
NO_SCOPED_PTR(A)
NO_SHARED_PTR(A)
Another option would be to overload new and delete for those classes and make delete private or protected. instrusive_ptr_release could then be made a friend function or similar technique used to actually invoke delete when the ref count dropped to zero.
I often come accross the problem that I have a class that has a pair of Register/Unregister-kind-of-methods. e.g.:
class Log {
public:
void AddSink( ostream & Sink );
void RemoveSink( ostream & Sink );
};
This applies to several different cases, like the Observer pattern or related stuff. My concern is, how safe is that? From a previous question I know, that I cannot safely derive object identity from that reference. This approach returns an iterator to the caller, that they have to pass to the unregister method, but this exposes implementation details (the iterator type), so I don't like it. I could return an integer handle, but that would require a lot of extra internal managment (what is the smallest free handle?). How do you go about this?
You are safe unless the client object has two derivations of ostream without using virtual inheritance.
In short, that is the fault of the user -- they should not be multiply inheriting an interface class twice in two different ways.
Use the address and be done with it. In these cases, I take a pointer argument rather than a reference to make it explicit that I will store the address. It also prevents implicit conversions that might kick in if you decided to take a const reference.
class Log {
public:
void AddSink( ostream* Sink );
void RemoveSink( ostream* Sink );
};
You can create an RAII object that calls AddSink in the constructor, and RemoveSink in the destructor to make this pattern exception-safe.
You could manage your objects using smart pointers and compare the pointers for equality inside your register / deregister functions.
If you only have stack allocated objects that are never copied between an register and deregister call you could also pass a pointer instead of the reference.
You could also do:
typedef iterator handle_t;
and hide the fact that your giving out internal iterators if exposing internal data structures worries you.
In your previous question, Konrad Rudolph posted an answer (that you did not accept but has the highest score), saying that everything should be fine if you use base class pointers, which you appear to do.