qRegisterMetaType , the custom class must have defalut constructor? how about a class only have constructor with params?



  • qRegisterMetaType , the custom class must have defalut constructor? how about a class only have constructor with params?


  • Lifetime Qt Champion

    Hi,

    The constructor may have parameters as long as they all have default values. Take for example QEasingCurve



  • @SGaist thank you...so if the Class only have constructor with param, it cannot qRegisterMetaType ?

    and if i add a default constuctor...is it right? because there is only constructor with param before....and the new added default constructor is useless actually and only used when qRegisterMetaType ...



  • If your class doesn't make sense when created by a default constructor, it's sensible to explicitly forbid the default constructor. That means you cannot register it. Alternatively, you can register YourClass* instead of the YourClass.

    If you want to register your class, maybe you need to rethink how it works and what it does.



  • @Asperamanca
    Q_DECLARE_METATYPE(MyClass * );
    qRegisterMetaType<MyClass * >();
    then i only use MyClass* or const MyClass* in the signal& slot's parma

    is all this right?



  • @opengpu2
    Yes, that's an alternative. Just be aware of the implications: You no longer have a copy of the object, if the signal-slot connection is queued, your pointer might be invalid, etc.



  • @Asperamanca thank you...but my signal-slot connection is queued....
    is there any solution for my situation??



  • The best way in my opinion is to have a class with a default constructor which contains exactly the data you want to transmit. This might be a part of the class you have right away. If you describe your current class in more detail, I might be able to make a better suggestion.

    You could transfer a smart pointer to your class via signal-slot, and if you code it consistently, it works. But I find it to be an awkward solution.



  • @Asperamanca
    class MyClass
    {
    public:
    MyClass(Enum e, Pointer* p = NULL) : m_e(e), m_p(p) { }
    ~MyClass() {}
    private:
    Enum m_e;
    Pointer* m_p;
    }



  • In this case, the question is not about MyClass, but what happens to the Pointer it holds. So even if you were to successfully transmit MyClass via signal-slot, Pointer might be invalid by the time the slot is handled. Since I don't know what Pointer is about, it's hard to suggest a good solution here.

    The question you might want to ask yourself is whether you want to use signals-slots to
    a) transmit data (anything that can in the end be disassembled into primitive types, and that can be copied), or
    b) object identities (like "exactly this browser window" - which cannot just be copied).

    If the answer is that you want to transmit data which can be copied, it's best to provide a class which holds the complete data and can be copied. If the object contains a lot of data, use of implicit sharing might be a good idea (and is easy to implement)
    If the answer is that you want to transmit identities, then I would change MyClass to hold a smart pointer to p, and check (within the slot) whether the object is still valid before using it.



  • @Asperamanca thank you, my situation is:

    //in the 2nd thread:
    void thread::run()
    {
        MyClass myClass(eInvalid);
        while (xxx->fill(myClass))
        {
            emit signal(myClass);
        }
    }
    
    //in the main thread:
    void slot(const MyClass * myClass)
    {
    ...
    }
    


  • @Asperamanca so even i just write a default constructor Only for qRegisterMetaTye...it's still wrong to crosss the thread...right?



  • @Asperamanca i have a solution:

    //in the 2nd thread:
    void thread::run()
    {
        MyClass myClass(eInvalid);
        while (xxx->fill(myClass))
        {
            //emit signal(myClass);
            g_queue.enqueue(myClass);
            emit signal();
        }
    }
    
    //in the main thread:
    //void slot(const MyClass * myClass)
    void slot()
    {
        while (!g_queue.isEmpty())
        {
            MyClass myClass = g_queue.dequeue();
            ........
        }
    }
    

    is it able to work ?
    and is there any better solution for this situation?



  • As long as the responsibilities are clear about who creates an object and who destroys it, it's all right. In that case you can even send a pointer via signal/slot. The one advantage I see in using a queue like you do here is that cleanup is much easier if the application terminates while some signals are still pending.

    An alternative would be to give the responsibility of m_p's lifetime to MyClass. If done right, you could then just send MyClass (not MyClass*) via signals and slots. The catch is that you will need a copy constructor, and handle reference counting for MyClass, either yourself or by using smart pointers inside MyClass.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.