0

Given a simple class that has a private member for instance a

double *data_series

This member is allocated and filled with data from a qt slot like so:

int channel_count = ...
data = new double[channel_count];
std::copy(input_data, input_data+channel_count, data);

in the dtor of this class the data ptr is deleted.

Now, this simple class holds small samples of data that are retrieved and each of theses classes/frames are emitted and should then be handled by all the connected slots in a good way, note that the data pointed by the data ptr is never modified, just read.

I am not too good at smart pointers so first I had the case with only one slot connected so not a big issue, I could just emit pointer to the class and delete the class in the slot when done. The problem arises when multiple slots are connected, the data pointer should only be deleted when all slots are done with the data. I can not emit the class by value since I dont want to have a copy ctor that duplicates the data all the time.

So, should I emit some kind of smart pointer to the class? Or should I manage the data pointer using a smart pointer somehow. I am looking for a good pattern here for me to follow.

brgds

Daniel Wedlund
  • 804
  • 7
  • 18
  • Did you try using ``QSharedPointer``? The memory gets free'd/deleted upon the last reference of QSharedPointer is deleted. – Sebastian Lange Jul 30 '14 at 08:51
  • I tried to emit the pointer to the class as a QSharedPointer and it seems to work out well. However I struggle to find a good pattern, I wonder if I should declare the data pointer as a shared pointer and then just emit the instance of the class... the default copy operator would then automatically copy the QSharedPointer and all other parameters I guess ... and when the last instance is deleted it should delete the data pointed by the shared pointer ... – Daniel Wedlund Jul 30 '14 at 13:54
  • Copy constructors of Qt containers don't copy the data. – Kuba hasn't forgotten Monica Aug 01 '14 at 13:48

2 Answers2

0

Use QSharedPointer with custom deleter. If you use it as signal/slot parameter, call qRegisterMetatype before connecting signal/slots.

Here's an example of deleter usage example

Community
  • 1
  • 1
Nikita
  • 950
  • 8
  • 19
  • I have it all working using a QSharedPointer and in my case the destructor of the class frees the memory pointed to by the data ptr. And this only happens once thanks to the QSharedPointer. Thank you for the example thou! So in short, what I am asking for is a good pattern that sasy to do 1, 2 or 3: 1) use a QSharedPointer for the class 2) use a QSharedPointer for the member variable that is dynamically allocated 3) do something else?? :) – Daniel Wedlund Jul 30 '14 at 13:57
  • I'd use the same strategy as for any other regular c++ class, depends on your programming style and particular situation. – Nikita Jul 30 '14 at 14:42
0

Since you program in C++, you should be using containers. This then takes care of all the pesky details for you and simply works.

class Class : public QObject {
  Data m_data;
  ...
public:
  typedef QVector<double> Data;
  // The signal and slot declarations MUST use fully qualified types!
  Q_SIGNAL void hasData(const Class::Data &);
  ...
  Q_SLOT void processData() {
    Data localData(m_data);
    ...
    // you can modify localData here
    ...
    emit hasData(localData);
    ...
  }
}
Q_DECLARE_METATYPE(Class::Data)

int main(int argc, char ** argv)
{
  ...
  qRegisterMetatype<Class::Data>();
  ...
}

It is important to realize that the moc treats types as strings, so that you must both declare and use the fully qualified type.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313