Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QObject-derived values in container classes [modified]
QtWS25 Last Chance

QObject-derived values in container classes [modified]

Scheduled Pinned Locked Moved General and Desktop
14 Posts 4 Posters 8.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    alexxx_1992
    wrote on last edited by
    #1

    When I use my own class as signal/slot parameter, compiller shows me error: error C2248: error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'. I tried to redifine default construcor for my class and to define operator = for it.
    I tried to pass my class as poiner and as reference. This had no effect.

    Signal's argument class:
    header file:
    @#ifndef CARD_H
    #define CARD_H

    #include <QtGui/QtGui>

    class Card: public QObject
    {
    Q_OBJECT

    enum Suit
    {
    Crosses, Spades, Hearts, Diamonds
    } m_suit;

    enum Value
    {
    Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace
    } m_value;

    QPixmap m_face;
    public:
    Card (Suit _suit, Value _value, QObject *_parent = NULL);
    /Card (const Card &_card);
    Card ();
    /
    };

    #endif // CARD_H@

    source file:
    @#include "card.h"

    Card::Card (Suit _suit, Value _value, QObject *_parent)
    : QObject (_parent)
    {
    m_suit = _suit;
    m_value = _value;
    //m_pFace = new QPixmap; // путь к файлу
    }@

    Class with slot connected with signal:
    header:
    @#ifndef ABSTRACTPOKERPLAYER_H
    #define ABSTRACTPOKERPLAYER_H

    #include "card.h"
    #include "abstractplayer.h"

    class AbstractPokerPlayer: public AbstractPlayer
    {
    Q_OBJECT
    QVector<Card> m_cards;

    public:
    AbstractPokerPlayer (const QString& _name, double _balance = 10000.0, QObject *_parent = NULL);

    public slots:
    void slotAddCard (Card *_card);
    virtual void slotDoStep (QString& _playerName, QVector<AbstractStep> *_steps);
    };

    #endif // ABSTRACTPOKERPLAYER_H
    @

    source:
    @#include "abstractpokerplayer.h"

    AbstractPokerPlayer::AbstractPokerPlayer (const QString &_name, double _balance, QObject *_parent)
    : AbstractPlayer(_name, _balance, _parent)
    {
    m_cards.resize (2);
    }

    void AbstractPokerPlayer::slotAddCard (Card _card)
    {
    if (m_cards.size () <= 2)
    m_cards.push_back (
    _card);
    }@

    Please, help me.

    Edit: modified topic title to reflect the actual problem as pointed out by Peppe; Andre

    Student

    1 Reply Last reply
    0
    • G Offline
      G Offline
      giesbert
      wrote on last edited by
      #2

      Hi,

      parameter of a signal must be packable into a QVariant.
      You can use your own class pointer if you declare the variant meta type for it:

      @
      qRegisterMetaType<Card*>("Card*");
      @

      With pass by value it is not usable as the base class (QObject) is not copyable and not assignable.
      Pass by reference is intern also a pass by value, which means --> same behavior.

      Nokia Certified Qt Specialist.
      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

      1 Reply Last reply
      0
      • A Offline
        A Offline
        alexxx_1992
        wrote on last edited by
        #3

        Thanks for fast answer!

        I'm add
        @qRegisterMetaType<Card*>("Card*");@
        to Card constructor, but compiller shows me the same errrors.
        Am I have to define default constructor or anything more?

        Student

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andre
          wrote on last edited by
          #4

          As Gerolf was pointing out: QObject derived classes can not be copied, and thus, not be stored in a QVariant, and thus, not be passed as arguments in a signal-slot connection.

          However, you can pass pointers to QObjects. Or you can pass a smart pointer object wrapping such a pointer to a QObject.

          1 Reply Last reply
          0
          • D Offline
            D Offline
            dangelog
            wrote on last edited by
            #5

            [quote author="Gerolf" date="1302073628"]Hi,

            parameter of a signal must be packable into a QVariant.
            You can use your own class pointer if you declare the variant meta type for it:

            @
            qRegisterMetaType<Card*>("Card*");
            @
            [/quote]
            This is false.

            In general, type registration is required only for queued connections. It's NOT necessary to do that for direct connections, no matter the datatype involved.

            [quote]
            With pass by value it is not usable as the base class (QObject) is not copyable and not assignable.
            Pass by reference is intern also a pass by value, which means --> same behavior.[/quote]

            False as well, passing by reference is simply passing by reference and it's allowed with QObjects. No copy takes place.

            Apart from these considerations, the OP's problem has nothing to do with signals and slots. Please change the topic title as well. He's making what IMHO appears to be a value class (the Card class) inherit from QObject, which makes it not copiable. Therefore, @ QVector<Card> m_cards; @ is invalid, as well as things like @ m_cards.push_back (*_card); @

            Software Engineer
            KDAB (UK) Ltd., a KDAB Group company

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #6

              Peppe, I think you are right. The (main) problem is in using container classes with QObject-derived value types. That won't work for the non-copyable reasons already mentioned.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                alexxx_1992
                wrote on last edited by
                #7

                I'm understand. Am I need to to do my Card class not inherit from QObject?

                Student

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on last edited by
                  #8

                  [quote author="alexxx_1992" date="1302076299"]I'm understand. Am I need to to do my Card class not inherit from QObject?[/quote]

                  No. Just store pointers to the objects instead of the objects themselves in your containers. So, instead of:

                  @
                  QVector<Card> m_cards;
                  @

                  You do:

                  @
                  QVector<Card*> m_cards; // <-- note the *
                  @

                  Or, alternatively, you store smart pointers in your container. Something like:

                  @
                  QVector<QPointer<Card> > m_cards;
                  @

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    giesbert
                    wrote on last edited by
                    #9

                    [quote author="peppe" date="1302075488"]
                    [quote]
                    With pass by value it is not usable as the base class (QObject) is not copyable and not assignable.
                    Pass by reference is intern also a pass by value, which means --> same behavior.[/quote]

                    False as well, passing by reference is simply passing by reference and it's allowed with QObjects. No copy takes place.
                    [/quote]

                    If it's used for queued connections, it is in fact copied. So you can't genrally say it's not copied. But I was also wrong it's not always copied :-)

                    Nokia Certified Qt Specialist.
                    Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      alexxx_1992
                      wrote on last edited by
                      #10

                      Thank you very much!!! It's works!!!)))
                      Sorry for my English)

                      Student

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andre
                        wrote on last edited by
                        #11

                        If you choose to store pointers in your container, don't forget to delete the objects in there when the container goes out of scope. That does not happen automatically. Considder adding something like this to your AbstractPokerPlayer destructor:

                        @
                        #include <QtAlgorithms>

                        qDeleteAll(m_cards);
                        m_cards.clear(); //not strictly needed
                        @

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          alexxx_1992
                          wrote on last edited by
                          #12

                          Thanks! I will try) I think they can't to be deleted automaticly because they are pointers and container don't have to take care about that memory. Am I rigth?

                          And… Could I pass into the signal QVector’s reference?

                          Edit: please use the edit option to add something to a posting you just made; Andre

                          Student

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on last edited by
                            #13

                            Well, the problem is, that the container will delete the contents of the container when it is deleted. Only in this case, the container contains only pointers. So it deletes the pointers, but it does not call delete on the pointers. That would be a memory leak, if there are no copies of those pointers elsewhere. I pointed out one way to fix that (do the deletion yourself at an appropriate time), but you could also use smart pointers to do it automatically.

                            You are allowed to pass a reference to your QVector in a signal, yes.

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              alexxx_1992
                              wrote on last edited by
                              #14

                              In this case, I will use smart pointers)
                              Thank you very much!

                              Student

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved