Reputation: 5807
In a bigger OpenSource project we have the problem of a dangling pointer somewhere. Instances of a polymorphic object are passed around via a pointer to it and stored in a couple of places. More specifically: A ware is passed around as a Ware*
which is allocated at one point and then registered in e.g. the building that ordered it and the carrier that currently holds it (and a couple of more places) The 'owner' is the place the physically 'has' it (e.g. the carrier). So when the carrier dies, he tells the ware to tell the building that ordered it that it no longer comes --> Building removes its pointer. Then the ware is deleted and no instance should have a pointer to it.
This works in most of the cases but there seems to be some conditions where this fails and an instance still has a pointer. I want to detect this. So I thought about replacing the Ware*
by a class WarePtr
that acts like a shared pointer (ref-counted). So when delete
is called, it can check, if the refCount==1
and assert this.
The problem: For most of the usages it is a drop-in replacement. So syntactic changes besides the replacement Ware*
->WarePtr
. But I'd also need to change the delete ware
calls which I would like to avoid so this could be removed without the need to change this back.
Is it possible to create a class or an overload so I can actually call delete ware
where it is defined as WarePtr ware
?
The called function would need to check the assertion and call delete
on the contained pointer. Overloading the delete operator
would only allow me to intercept calls to deleting a WarePtr*
...
Upvotes: 1
Views: 143
Reputation: 5135
I understand
detection of a constraint violation without overhead in release mode
I still suggest that you switch to shared_ptr
, it's the right thing to do. The overhead over plain pointers will be very small, well worth the benefits.
You can then test for the constraint violation in your destructor (or wherever you delete the pointer you gave out) like this:
reset()
the shared pointer that was holding your object to delete it.assert()
that the weak pointer is expired()
.Upvotes: 0
Reputation: 119229
If WarePtr
has a non-explicit conversion function to Ware*
, then you can call delete
on a WarePtr
.
If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section.
([expr.delete]/2)
Other than that, the operand must be a pointer.
Upvotes: 4