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. How to enable copy constructor in Qt
Forum Updated to NodeBB v4.3 + New Features

How to enable copy constructor in Qt

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 6 Posters 12.8k Views 6 Watching
  • 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.
  • yuvaramY Offline
    yuvaramY Offline
    yuvaram
    wrote on last edited by kshegunov
    #3

    Hi

    Below is sample code provided,

    class Test : public QObject
    {
        Q_OBJECT
    public:
        Test(QObject *parent = 0){
            qDebug()<<Q_FUNC_INFO<<endl;
        }
        Test(const Test &obj){
            qDebug()<<Q_FUNC_INFO<<endl;
        }
        ~Test(){
            qDebug()<<Q_FUNC_INFO<<endl;
        }
    signals:
        void testSignal();
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        Test *Tobj = new Test;
        Test *Tobj2 = new Test(*Tobj);
    
        return a.exec();
    }
    

    [Added code tags ~kshegunov]

    Yuvaram Aligeti
    Embedded Qt Developer
    : )

    E 1 Reply Last reply
    1
    • JohanSoloJ Offline
      JohanSoloJ Offline
      JohanSolo
      wrote on last edited by
      #4

      The short answer is you can't. You can find the complete answer there.

      `They did not know it was impossible, so they did it.'
      -- Mark Twain

      1 Reply Last reply
      4
      • yuvaramY yuvaram

        Hi

        Below is sample code provided,

        class Test : public QObject
        {
            Q_OBJECT
        public:
            Test(QObject *parent = 0){
                qDebug()<<Q_FUNC_INFO<<endl;
            }
            Test(const Test &obj){
                qDebug()<<Q_FUNC_INFO<<endl;
            }
            ~Test(){
                qDebug()<<Q_FUNC_INFO<<endl;
            }
        signals:
            void testSignal();
        };
        
        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
        
            Test *Tobj = new Test;
            Test *Tobj2 = new Test(*Tobj);
        
            return a.exec();
        }
        

        [Added code tags ~kshegunov]

        E Offline
        E Offline
        Eeli K
        wrote on last edited by
        #5

        @yuvaram This can be compiled and run:

        #include <QCoreApplication>
        #include <QDebug>
        
        class Test : public QObject
        {
        Q_OBJECT
        public:
        Test(QObject *parent = 0){
        qDebug()<<Q_FUNC_INFO<<endl;
        }
        Test(const Test &obj):QObject(nullptr){
        qDebug()<<Q_FUNC_INFO<<endl;
        }
        ~Test(){
        qDebug()<<Q_FUNC_INFO<<endl;
        }
        signals:
        void testSignal();
        };
        
        #include "main.moc"
        
        int main(int argc, char *argv[])
        {
        QCoreApplication a(argc, argv);
        
        Test *Tobj = new Test;
        Test *Tobj2 = new Test(*Tobj);
        
        return a.exec();
        
        }
        

        As explained in Qt docs it's a clone, not a copy. Basically it's a new object which copies only the relevant parts of the existing object. Consider also the rule of three/five/zero, http://en.cppreference.com/w/cpp/language/rule_of_three.

        Maybe it would be better to not make it like a copy constructor by making a separate init or clone function which takes the existing object. That would avoid possible confusion. Someone with more experience can give an opinion here.

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

          Other option: Split the class into a data part (which is not derived of QObject, and fully copyable) and a functionality part. That way, you could do something like this:

          Test *Tobj = new Test;
          Test *Tobj2 = new Test(*Tobj.data());
          
          1 Reply Last reply
          2
          • E Eeli K

            @yuvaram This can be compiled and run:

            #include <QCoreApplication>
            #include <QDebug>
            
            class Test : public QObject
            {
            Q_OBJECT
            public:
            Test(QObject *parent = 0){
            qDebug()<<Q_FUNC_INFO<<endl;
            }
            Test(const Test &obj):QObject(nullptr){
            qDebug()<<Q_FUNC_INFO<<endl;
            }
            ~Test(){
            qDebug()<<Q_FUNC_INFO<<endl;
            }
            signals:
            void testSignal();
            };
            
            #include "main.moc"
            
            int main(int argc, char *argv[])
            {
            QCoreApplication a(argc, argv);
            
            Test *Tobj = new Test;
            Test *Tobj2 = new Test(*Tobj);
            
            return a.exec();
            
            }
            

            As explained in Qt docs it's a clone, not a copy. Basically it's a new object which copies only the relevant parts of the existing object. Consider also the rule of three/five/zero, http://en.cppreference.com/w/cpp/language/rule_of_three.

            Maybe it would be better to not make it like a copy constructor by making a separate init or clone function which takes the existing object. That would avoid possible confusion. Someone with more experience can give an opinion here.

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by kshegunov
            #7

            @Eeli-K said in How to enable copy constructor in Qt:

            Basically it's a new object which copies only the relevant parts of the existing object.

            Which begs the question what are the relevant parts? Are signal-slot connections relevant, is parent-child relationship relevant, or is only the contained data relevant?
            As @JohanSolo noted even if you can trick the library to provide a copy constructor, this doesn't necessarily mean you should (actually quite the opposite). In short you should not need to copy QObjects (or their subclasses), they are not designed to be copied to begin with.

            Here's the full discussion:
            http://doc.qt.io/qt-5.6/object.html#identity-vs-value

            Read and abide by the Qt Code of Conduct

            E 1 Reply Last reply
            4
            • kshegunovK kshegunov

              @Eeli-K said in How to enable copy constructor in Qt:

              Basically it's a new object which copies only the relevant parts of the existing object.

              Which begs the question what are the relevant parts? Are signal-slot connections relevant, is parent-child relationship relevant, or is only the contained data relevant?
              As @JohanSolo noted even if you can trick the library to provide a copy constructor, this doesn't necessarily mean you should (actually quite the opposite). In short you should not need to copy QObjects (or their subclasses), they are not designed to be copied to begin with.

              Here's the full discussion:
              http://doc.qt.io/qt-5.6/object.html#identity-vs-value

              E Offline
              E Offline
              Eeli K
              wrote on last edited by
              #8

              @kshegunov Of course. The writer of a class decides what is relevant for their needs. As can be seen in my example, the QObject is not copied, a default object with no parent is constructed. If one wants to copy some data, it must be done explicitly in the constructor, wheter it's QObject's data or the inherited class data. What I wonder is whether the copy constructor syntax should be used at all if the constructor doesn't really make a copy. It's coding style, but is it bad or good?

              kshegunovK 1 Reply Last reply
              0
              • E Eeli K

                @kshegunov Of course. The writer of a class decides what is relevant for their needs. As can be seen in my example, the QObject is not copied, a default object with no parent is constructed. If one wants to copy some data, it must be done explicitly in the constructor, wheter it's QObject's data or the inherited class data. What I wonder is whether the copy constructor syntax should be used at all if the constructor doesn't really make a copy. It's coding style, but is it bad or good?

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by
                #9

                @Eeli-K said in How to enable copy constructor in Qt:

                The writer of a class decides what is relevant for their needs.

                He might not know. What do you do with signals and slots? Suppose you have a number of listeners for a signal, do you reconnect them to the new object, do you connect only part of them or not at all? It may depend on a context that's beyond the capabilities for a copy constructor or clone function or w/e to decide.

                Read and abide by the Qt Code of Conduct

                E 1 Reply Last reply
                1
                • kshegunovK kshegunov

                  @Eeli-K said in How to enable copy constructor in Qt:

                  The writer of a class decides what is relevant for their needs.

                  He might not know. What do you do with signals and slots? Suppose you have a number of listeners for a signal, do you reconnect them to the new object, do you connect only part of them or not at all? It may depend on a context that's beyond the capabilities for a copy constructor or clone function or w/e to decide.

                  E Offline
                  E Offline
                  Eeli K
                  wrote on last edited by
                  #10

                  @kshegunov Now I really don't understand. Maybe we are talking about different things. If the writer of a class doesn't know what an object could need he can't write the class. If an object needs to copy some data from another object, it can be copied in one way or another. If the writer has to write (simplified):

                  MyClass a;
                  //...change a...
                  MyClass b;
                  b.x = a.x;
                  b.y = a.y;
                  

                  and has to do it often, it can be moved to a function

                  MyClass b(a);
                  

                  or

                  MyClass b;
                  b.init(a);
                  

                  or

                  b.clone(a);
                  

                  or whatever. You can use copy constructor syntax (MyClass(const MyClass&)) for it as I demonstrated; whether you should is another thing. What I asked was about this: should this syntax be left for the real copying only or is it OK to use it for (partly) cloning?

                  kshegunovK 1 Reply Last reply
                  0
                  • E Eeli K

                    @kshegunov Now I really don't understand. Maybe we are talking about different things. If the writer of a class doesn't know what an object could need he can't write the class. If an object needs to copy some data from another object, it can be copied in one way or another. If the writer has to write (simplified):

                    MyClass a;
                    //...change a...
                    MyClass b;
                    b.x = a.x;
                    b.y = a.y;
                    

                    and has to do it often, it can be moved to a function

                    MyClass b(a);
                    

                    or

                    MyClass b;
                    b.init(a);
                    

                    or

                    b.clone(a);
                    

                    or whatever. You can use copy constructor syntax (MyClass(const MyClass&)) for it as I demonstrated; whether you should is another thing. What I asked was about this: should this syntax be left for the real copying only or is it OK to use it for (partly) cloning?

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #11

                    @Eeli-K said in How to enable copy constructor in Qt:

                    If the writer of a class doesn't know what an object could need he can't write the class.

                    Signals are "special". When you design your class you don't know what will be connected to a signal, so you can't know how the user will connect that signal and what will be attached to it. Even if you accept that all dynamic properties (as Qt allows those) are to be copied, which again is dubious, as you have no information at the time of writing the class what those might represent, you have no information what to do with any signal-slot connections in which the object participates.
                    Yes, it's possible to copy stuff around, but you will probably never be able to make it work reliably.

                    Same goes for the parent-child relationships. Is the object to be part of the same hierarchy as the one you copy from? If yes, why, if not, why not? This could mean the difference between objects living in one thread and their "copies" living in another and at time of writing of your copy routine or copy constructor, or w/e method you use you don't have the whole picture.

                    What I asked was about this: should this syntax be left for the real copying only or is it OK to use it for (partly) cloning?

                    What you could do was suggested by @Asperamanca - split the data that is to be copyable from the QObject. Then you know what is what - the QObject is an identity, but it can aggregate copyable data. So whenever you need you know the data can be copied safely and you leave the user to tinker on "how" and "why" with the QObject part, he/she already has the usage pattern and the info, you as a class writer don't.

                    Read and abide by the Qt Code of Conduct

                    E 1 Reply Last reply
                    1
                    • kshegunovK kshegunov

                      @Eeli-K said in How to enable copy constructor in Qt:

                      If the writer of a class doesn't know what an object could need he can't write the class.

                      Signals are "special". When you design your class you don't know what will be connected to a signal, so you can't know how the user will connect that signal and what will be attached to it. Even if you accept that all dynamic properties (as Qt allows those) are to be copied, which again is dubious, as you have no information at the time of writing the class what those might represent, you have no information what to do with any signal-slot connections in which the object participates.
                      Yes, it's possible to copy stuff around, but you will probably never be able to make it work reliably.

                      Same goes for the parent-child relationships. Is the object to be part of the same hierarchy as the one you copy from? If yes, why, if not, why not? This could mean the difference between objects living in one thread and their "copies" living in another and at time of writing of your copy routine or copy constructor, or w/e method you use you don't have the whole picture.

                      What I asked was about this: should this syntax be left for the real copying only or is it OK to use it for (partly) cloning?

                      What you could do was suggested by @Asperamanca - split the data that is to be copyable from the QObject. Then you know what is what - the QObject is an identity, but it can aggregate copyable data. So whenever you need you know the data can be copied safely and you leave the user to tinker on "how" and "why" with the QObject part, he/she already has the usage pattern and the info, you as a class writer don't.

                      E Offline
                      E Offline
                      Eeli K
                      wrote on last edited by
                      #12

                      @kshegunov OK, I think I understand better now. You are talking about the QObject. But I implicitly already accepted that from the beginning. In my example, modified from the original, which is legal C++ there was:

                      Test(const Test &obj):QObject(nullptr){
                      qDebug()<<Q_FUNC_INFO<<endl;
                      }
                      

                      which means the QObject is not copied, right? In the constructor any data can be copied manually if the writer wants so. I haven't suggested that all data should be copied blindly. Only the data which is relevant for the needs, possibly only from the Test class. Then I wondered if it's better to use some other than copy ctor syntax because this will not make a real copy anyways. I didn't answer the original question but wasn't explicit about that, so maybe you thought I was talking about somehow enabling QObject copying?

                      kshegunovK 1 Reply Last reply
                      0
                      • E Eeli K

                        @kshegunov OK, I think I understand better now. You are talking about the QObject. But I implicitly already accepted that from the beginning. In my example, modified from the original, which is legal C++ there was:

                        Test(const Test &obj):QObject(nullptr){
                        qDebug()<<Q_FUNC_INFO<<endl;
                        }
                        

                        which means the QObject is not copied, right? In the constructor any data can be copied manually if the writer wants so. I haven't suggested that all data should be copied blindly. Only the data which is relevant for the needs, possibly only from the Test class. Then I wondered if it's better to use some other than copy ctor syntax because this will not make a real copy anyways. I didn't answer the original question but wasn't explicit about that, so maybe you thought I was talking about somehow enabling QObject copying?

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #13

                        @Eeli-K said in How to enable copy constructor in Qt:

                        which is legal C++ there was:
                        [... snip ...]
                        which means the QObject is not copied, right

                        Yes, it's legal, and yes it's not copied. What I'm trying to argue here is you should not enable the copy constructor to begin with. It's confusing for the user, as your copy constructor doesn't actually copy, and not really productive. Instead, you could just add a constructor that accepts the relevant data as a paremeter, e.g.:

                        Test(const DataToBeUsed & data, ..., QObject * parent = nullptr)
                            : QObject(parent)
                        {
                            // Do stuff with the data now
                        }
                        

                        Read and abide by the Qt Code of Conduct

                        E 1 Reply Last reply
                        1
                        • kshegunovK kshegunov

                          @Eeli-K said in How to enable copy constructor in Qt:

                          which is legal C++ there was:
                          [... snip ...]
                          which means the QObject is not copied, right

                          Yes, it's legal, and yes it's not copied. What I'm trying to argue here is you should not enable the copy constructor to begin with. It's confusing for the user, as your copy constructor doesn't actually copy, and not really productive. Instead, you could just add a constructor that accepts the relevant data as a paremeter, e.g.:

                          Test(const DataToBeUsed & data, ..., QObject * parent = nullptr)
                              : QObject(parent)
                          {
                              // Do stuff with the data now
                          }
                          
                          E Offline
                          E Offline
                          Eeli K
                          wrote on last edited by
                          #14

                          @kshegunov said in How to enable copy constructor in Qt:

                          What I'm trying to argue here is you should not enable the copy constructor to begin with. It's confusing for the user, as your copy constructor doesn't actually copy, and not really productive.

                          This actually directly answered my question. Don't use the copy ctor syntax if it doesn't make a real copy.

                          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