2

I have read many threads regarding this, but I couldn't find an answer to this

In my Qt application, I am using QSignalSpy to catch a signal. It has a user-defined datatype for one of its parameters. To catch such a parameter, I have to first register that datatype with Qt using QMetaType and using the macro Q_DECLARE_METATYPE. It says

This macro makes the type Type known to QMetaType as long as it provides a public default constructor, a public copy constructor and a public destructor. It is needed to use the type Type as a custom type in QVariant.

The problem: I have a class CustomData with only constructor defined. Now unless I explicitly declare a destructor and a copy constructor, Qt throws an error. I want to use the implicit destructor and copy constructor that C++ gives. For destructor, I used

~CustomData() = default;

which uses the default destructor. But I cannot use a similar statement for the copy constructor. Will using

CustomData( const CustomData& ) {};

invoke the implicit copy constructor?

(I am doing this because I want to retain the behavior of the implicit copy constructor) Thanks in advance.

The CustomData class is shown below

#include <QMetaType>
#include <QString>

class CustomData : public QObject
{
Q_OBJECT

public:
  CustomData(QObject *parent = NULL);
  ~CustomData() = default; // I added this line
  //Will the next line call the implicit copy constructor?
  CustomData(const CustomData&) {}; //I added this line


  enum CustomMode {mode1, mode2, mode3};

  void somePublicMethod();

signals:
  void completed(CustomData *data);

private slots:
  void customComplete();

private:
  CustomMode _mode;
  QString _path;

  CustomData *_chained;
};

Q_DECLARE_METATYPE(CustomData)
clearScreen
  • 1,002
  • 4
  • 15
  • 31
  • What do you mean, cant you do `CustomData(const CustomData&) = default;`? Why can't you do that? Do you mean that the *editor* gives you an error, or the *compiler* when you build? – Some programmer dude Mar 10 '16 at 12:49
  • take a look at this thread -- (http://stackoverflow.com/questions/1810163/c-implicit-copy-constructor-for-a-class-that-contains-other-objects) – akashrajkn Mar 10 '16 at 12:49
  • @JoachimPileborg , using that code, qt throws an error which is the same error when I dont declare any copy constructor – clearScreen Mar 10 '16 at 12:50
  • 1
    When you say "qt throws an error", what do you mean by that? Because that is how you tell the compiler to use the default compiler-generated copy constructor. Do you mean that your editor or IDE says it's wrong? Do you mean you get an error when actually building? Can you tell us *what* error you get? – Some programmer dude Mar 10 '16 at 12:52
  • @JoachimPileborg -- I get a build error--- synthesized method ‘CustomData::CustomData(const CustomData&)’ first required here return new T(*static_cast(t)) – clearScreen Mar 10 '16 at 12:54
  • 1
    `QObject` is non copyable so I guess the default copy constructor cannot be generated. What invokes copying of this object? The signal in your code uses a pointer. Anyhow, if QT still passes it by value somewhere, maybe pass the data around as `std::unique_ptr` ? – Rudolfs Bundulis Mar 10 '16 at 13:21
  • @clearScreen you should really use `Q_DECLARE_METATYPE(CustomData*)` instead of `Q_DECLARE_METATYPE(CustomData)`. – Rudolfs Bundulis Mar 10 '16 at 14:27

2 Answers2

2

In short - it doesn't matter. Your implementation does not(hopefully) cause any effect.

If you go through the Qt documentation, it says as follows

QObject has neither a copy constructor nor an assignment operator. This is by design. Actually, they are declared, but in a private section with the macro Q_DISABLE_COPY(). In fact, all Qt classes derived from QObject (direct or indirect) use this macro to declare their copy constructor and assignment operator to be private.

Go through this -- Q_DISABLE_COPY().

This dictates that you use pointers to do the work. Look at this thread which discusses on how to copy object in Qt.

Community
  • 1
  • 1
akashrajkn
  • 2,295
  • 2
  • 21
  • 47
  • But OP has even given an error where copy constructor is instantiated - `new T(*static_cast(t))`. So the phrase " I believe you won't find an instance where the code employs the use of copy constructor" is kind of useless. – Rudolfs Bundulis Mar 10 '16 at 14:10
1

Actually the given code compiles without errors on Visual Studio 2013. However if the signature of the signal is changed to void completed(CustomData data); then a similar error occurs. Since you have not specified the compiler, but I assume it is gcc/clang you could get the error because template handling differs a bit. If so, the error is most likely caused by Q_DECLARE_METATYPE(CustomData) since it tries to generate the copy constructor inside. Change it to Q_DECLARE_METATYPE(CustomData*) (because that is what you really need, you are queuing arguments of type CustomData* not CustomData, at least in the given sample) and if you really have no signals that send the CustomData instances by value you should be fine.

Also, if you are passing the object by pointer then you should use Q_DECLARE_METATYPE(CustomData*). But I'd advise passing it through a std::unique_ptr or std::shared_ptr to prevent memory leaks.

Rudolfs Bundulis
  • 11,636
  • 6
  • 33
  • 71