I have an object which emits a signal with an object:
MyObj *obj = this->generateObj();
emit newObjSignal(obj);
delete obj;
and I have one or more people who connect to this. The problem is that the delete call gets called before the objects receive the signal. How do I deal with this?
Use smart pointers, so that memory management will be handled automatically and you will be sure you will have:
In this case, it seems to me std::shared_ptr<>
(or std::tr1::shared_ptr<>
or boost::shared_ptr<>
if you are not working with C++11) is the correct choice:
#include <memory> // For std::shared_ptr<>
// ...
std::shared_ptr<MyObj> obj(this->generateObj());
emit_new_signal(obj);
// delete obj; // <== No need for this anymore!
Also notice, that the handler functions will have to accept a std::shared_ptr<MyObj>
rather than a raw pointer MyObj*
, but the code inside those handlers won't have to be changed, because std::shared_ptr
provides an overload of operator ->
.
Notice that, in general, the use of new
is discouraged in C++11, and when possible one should use std::make_shared<>
to create shared_ptr
s. Thererfore, you may want to rewrite your generateObj()
member function so that it returns an std::shared_ptr<MyObj>
instead of a MyObj*
, and let it use std::make_shared<MyObj>()
internally to instantiate the object.
NOTE:
As pointed out by Geier in the comments, Qt has its own smart pointer class QSharedPointer that you may want to use.
While you can use a QSharedPointer
, another approach is to not use dynamic memory allocation. The code would therefore be -
MyObj obj = this->generateObj();
emit newObjSignal(obj);
This will obviously result in copies of MyObj
being created. Qt generally solves this issue by using implicit sharing or copy-on-write.
In order for your own class to use this implicit sharing mechanism you will have to change the structure of your class and use QSharedData
and QSharedDataPointer
class MyObjData : public QSharedData {
public:
int variable;
};
class MyObj {
MyObj() : d(new MyObjData) {}
int foo() { return d->variable; }
private:
QSharedDataPointer<MyObjData> d;
};
This way copies of MyObj
would be very cheap and you can easily pass it over a signal.
This is IMO a lot cleaner than using a QSharedPointer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With