10

I have a class which is publicly inherited from QWidget:

class MyWidget : public QWidget { Q_OBJECT public: MyWidget(const MyWidget& other) : obj1(other.obj1), obj2(other.obj2) private: some_class obj1; some_class obj2; }; 

When I built my project, compiler complains:

WARNING:: Base class "class QWidget" should be explicitly initialized in the copy constructor.

I checked out from other questions on stackoverflow, and got my answer. But the fact is, when I added that initialization like this:

class MyWidget : public QWidget { Q_OBJECT public: MyWidget(const MyWidget& other) : QWidget(other), //I added the missing initialization of Base class obj1(other.obj1), obj2(other.obj2) private: some_class obj1; some_class obj2; }; 

I got compile error:

QWidget::QWidget(const QWidget&) is private within this context

So, please explain me what I am doing wrong.

3
  • 5
    It seems that QWidget is not designed to be copy constructible, which means your derived type should not be either. Commented Sep 30, 2013 at 11:03
  • Did you explicitly create a copy constructor for QWidget or you left it to the compiler? Commented Sep 30, 2013 at 11:08
  • I don't need to create a Copy-Constructor for QWidget. I can just initialize the object calling QWidget::Cpoy-Constructor in the init list of my object's copy constructor. Commented Sep 30, 2013 at 11:11

3 Answers 3

22

QObject Class description page tells :

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. The reasoning is found in the discussion on Identity vs Value on the Qt Object Model page.

That means you are not supposed to copy QT objects, since QObject is non-copyable by design.

The first warning tells you to initialize the base class (which is QWidget). If you want to do this, you are going to construct a new base object, and I doubt that is what you want to do.

The second error is telling you what I wrote above : do not copy qt objects.

Sign up to request clarification or add additional context in comments.

Comments

14

All Qt classes are noncopyable by deriving from QObject.

It is common practice in C++ to forbid certain value-semantic operations like copying on polymorphic objects. Qt gives some examples of the problems that would arise if copy was allowed for QObject in its documentation:

A Qt Object...

  • might have a unique QObject::objectName(). If we copy a Qt Object, what name should we give the copy?
  • has a location in an object hierarchy. If we copy a Qt Object, where should the copy be located?
  • can be connected to other Qt Objects to emit signals to them or to receive signals emitted by them. If we copy a Qt Object, how should we transfer these connections to the copy?
  • can have new properties added to it at runtime that are not declared in the C++ class. If we copy a Qt Object, should the copy include the properties that were added to the original?

Comments

0

My previous answer wasn't adequate and removing Q_OBJECT macro removes the ability to use signals and slots. Hopefully this is more helpful as it also solved my problem.

As Qt doesn't allow copying of QWidgets, that essentially means you cannot use references, both in constructors and in my case, slots.

I had this code:

private slots: void updateName(MyWidget); 

and that was generating the compiler error because MyWidget is not a pointer.

In your class, you have MyWidget(const MyWidget& other) which is also not a pointer, your class should look like this:

class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(MyWidget* widget, QWidget* parent = 0); private: some_class obj1; some_class obj2; }; 

and the constructor code as this:

MyWidget::MyWidget(MyWidget* widget, QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) // if using a .ui file to build form { ... // ex: this->obj1 = widget->obj1 // this->obj2 = widget->obj2 } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.