PDA

View Full Version : emitting QSharedPointer



babu198649
23rd July 2010, 16:59
Hi,
I got a compiler error when i tried to emit QSharedPointer
QObject::connect: Cannot queue arguments of type 'QSharedPointer<MyClass>'. So i tried this

Q_DECLARE_METATYPE(QSharedPointer<MyClass> >); and
qRegisterMetaType<QSharedPointer<MyClass> > ("MyClassSharedPointer");

But still i get the warning. How to register the QSharedPointer class.

TemporalBeing
23rd July 2010, 19:57
Try:



...
typedef QSharedPointer<myClass> myClassSharedPointer;
Q_DECLARE_METATYPE(myClassSharedPointer);
...
qRegisterMetaType<myClassSharedPointer>("myClassSharedPointer");
...


That should do it for you.

[EDIT] Grammar correction

babu198649
23rd July 2010, 22:48
no even this fails, i am calling
qRegisterMetaType<myClassSharedPointer>("myClassSharedPointer");
in my MainWindow constructor.
and i have put the lines


typedef QSharedPointer<myClass> myClassSharedPointer;
Q_DECLARE_METATYPE(myClassSharedPointer);

in the myclass.h file after the class declaration.

is it fine?

wysota
23rd July 2010, 22:59
What is the point of emitting a QSharedPointer?

babu198649
24th July 2010, 06:12
What is the point of emitting a QSharedPointer?

The worker thread reads the files computes the data allocates and fills the memory with data, wraps it in QSharedPointer and passes it to the mainThread, which is used for plotting.
The problem of owner ship of the memory is avoided.

wysota
24th July 2010, 10:54
And how are you protecting the data structure inside the pointer object from being accessed simoultaneously from multiple threads? Does MyClass inherit QObject?

As for ownership - there is no problem of ownership here, if your class is just data that can be copied - simply don't use pointers but rather use objects (possibly based on QSharedData and friends).

babu198649
24th July 2010, 11:40
MyClass does not inherit anything. It just contains some variables and pointer which points to the dynamically allocated memory locations which are deleted in ~MyClass. Only the worker thread will write to the memory, the main thread will only read the memory area(although it is possible to write).

QSharedData and QSharedDataPointer requries comparitavely lot of work to be done(subclassing base class, implementing copy constructor, e.t.c) than using QSharedPointer which needs very less coding.

babu198649
24th July 2010, 11:42
Try:



...
typedef QSharedPointer<myClass> myClassSharedPointer;
Q_DECLARE_METATYPE(myClassSharedPointer);
...
qRegisterMetaType<myClassSharedPointer>("myClassSharedPointer");
...


That should do it for you.

[EDIT] Grammar correction

Thanks, it actually works. The problem earlier was i did not used the typdefed name in the slot and signal arguments.

I tried without using Q_DECLARE_METATYPE, still it worked.

SABROG
24th July 2010, 12:31
I write example, all works fine:



QT -= gui

TARGET = QSharedPointerQueue
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app

HEADERS += main.cpp
SOURCES += main.cpp




#include <QtCore/QCoreApplication>
#include <QtCore/QMetaType>
#include <QtCore/QSharedPointer>
#include <QtCore/QTextStream>

struct MyStruct
{
QString message;
};

Q_DECLARE_METATYPE(QSharedPointer<MyStruct>)

static void myStructDeleter(MyStruct* ms)
{
QTextStream(stdout)
<< "Do delete MyStruct with message: "
<< ms->message
<< endl;
delete ms;
}

class MyObject : public QObject
{
Q_OBJECT
public:
explicit MyObject(QObject* parent = 0) : QObject(parent) {}
virtual ~MyObject() {}

void sendMessage(const QString& message)
{
MyStruct* ms = new MyStruct;
ms->message = message;
emit sendPointer(QSharedPointer<MyStruct>(ms, myStructDeleter));
}

signals:
void sendPointer(QSharedPointer<MyStruct>);
};

class MyObjectTwo : public QObject
{
Q_OBJECT
public:
explicit MyObjectTwo(QObject* parent = 0) : QObject(parent) {}
virtual ~MyObjectTwo() {}

public slots:
void pointerReceiver(QSharedPointer<MyStruct> ptr)
{
QTextStream(stdout)
<< ptr->message
<< "(" << Q_FUNC_INFO << ")"
<< endl;
QCoreApplication::exit(0);
}
};

int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);

qRegisterMetaType<QSharedPointer<MyStruct> >();
MyObject mobj;
MyObjectTwo mobj2;

QObject::connect(&mobj, SIGNAL(sendPointer(QSharedPointer<MyStruct>)),
&mobj2, SLOT(pointerReceiver(QSharedPointer<MyStruct>)),
Qt::QueuedConnection);

mobj.sendMessage("Goodbye, cruel world!");

return a.exec();
}

#include "moc_main.cpp"



P.S.: Without Q_DECLARE_METATYPE compilator issue errors, so just try recompile project remove moc_* files first.

wysota
24th July 2010, 15:21
QSharedData and QSharedDataPointer requries comparitavely lot of work to be done(subclassing base class, implementing copy constructor, e.t.c)
Well, yeah... it's like... 10 lines of code :)

than using QSharedPointer which needs very less coding.
And much more debugging...

But QSharedPointer doesn't protect you from multithreaded access. If you write to an area of memory with one thread and at the same time read the same area in another thread there is a good chance you will get garbage on the reading side. QSharedPointer is not a solution here. It only prevents you from having to call delete on the object if you are carefull with how you access the object. But this is not your main concern here.

SABROG
26th July 2010, 07:05
Well, yeah... it's like... 10 lines of code :)
But QSharedPointer doesn't protect you from multithreaded access. If you write to an area of memory with one thread and at the same time read the same area in another thread there is a good chance you will get garbage on the reading side. QSharedPointer is not a solution here. It only prevents you from having to call delete on the object if you are carefull with how you access the object. But this is not your main concern here.

Why not? QSharedPointer is thread safe.


Thread-Safety

QSharedPointer and QWeakPointer are thread-safe and operate atomically on the pointer value. Different threads can also access the same QSharedPointer or QWeakPointer object at the same time without need for locking mechanisms.

It should be noted that, while the pointer value can be accessed in this manner, QSharedPointer and QWeakPointer provide no guarantee about the object being pointed to. Thread-safety and reentrancy rules for that object still apply.

wysota
26th July 2010, 09:51
Why not? QSharedPointer is thread safe.

As you quoted yourself:


It should be noted that, while the pointer value can be accessed in this manner, QSharedPointer and QWeakPointer provide no guarantee about the object being pointed to. Thread-safety and reentrancy rules for that object still apply.

QSharedPointer doesn't release you from care about thread synchronization regarding the data carried by the smart pointer. It only guarantees that operations on the pointer itself are atomic.