Subclass of QObject, qRegisterMetaType, and the private copy constructor

匿名 (未验证) 提交于 2019-12-03 01:57:01

问题:

I have a class that is a subclass of QObject that I would like to register as a meta-type. The QObject documentation states that the copy-constructor should be private, but the QMetaType documentation states that a type should have a public default constructor, a public copy constructor, and a public destructor.

I can override QObject's private copy constructor and declare a public copy constructor, but is this safe/ok/right?

class MyClass : public QObject {   Q_OBJECT   public:     MyClass();     MyClass(const MyClass &other);     ~MyClass(); } Q_DECLARE_METATYPE(MyClass); 

回答1:

It is not safe to make a QObject's copy constructor public. You can register a class pointer as the metatype, though. i.e.:

Q_DECLARE_METATYPE(MyClass*);

That's how Qt handles it with QObject and QWidget.



回答2:

What you're asking for is perfectly ok. You can't use QObjects copy constructor (it's private) in the implementation of your copy constructor, but then again, no-one forces you to:

class MyClass : public QObject {     Q_OBJECT public:     // ...     MyClass( const MyClass & other )         : QObject(), i( other.i ) {} // NOTE: calling QObject default ctor     // ... private:     int i; }; 

Depending on what services you need from QObject, you need to copy some properties over from other, in both the copy ctor and the copy assignment operator. E.g., if you use QObject for it's dynamic properties feature, you'd need to copy those, too:

    MyClass( const MyClass & other )         : QObject(), i( other.i )     {         Q_FOREACH( const QByteArray & prop, other.dynamicPropertyNames() )             setProperty( prop.constData(), other.property( prop.constData() ) );     } 

Likewise, if you want to maintain signal/slot connections.



回答3:

I use a separate copyValue(const MyClass & other) function to copy the data members that define the "values" of the MyClass instance. That ensures that I don't break the assumption of QObject unique identity, while still being able to duplicate the parts of the class that are defined at compile time.



回答4:

QTFruit fruit; QScriptValue scriptedFruitObject = engine.newQObject(&fruit); engine.globalObject().setProperty("fruit", scriptedFruitObject);   engine.setDefaultPrototype(qMetaTypeId(),                                 scriptedFruitObject);   QScriptValue qsMetaObject =         engine.newQMetaObject(fruit.metaObject());  engine.globalObject().setProperty("eLedState",                                        qsMetaObject);  int t = engine.evaluate("eLedState.On").toInteger();  engine.evaluate("fruit.fromJScript(1)"); engine.evaluate("fruit.fromJScript(eLedState.On)");  engine.evaluate("fruit.fromJScript(eLedState.TriState)");  //Create the ctor funtion QScriptValue qsFruitCtor =         engine.newFunction(QTFruitConstructor,                                 scriptedFruitObject); //Expose ctor to javascript  engine.globalObject().setProperty("QTFruit", qsFruitCtor);   //Create the QTFruit object engine.evaluate("var res = new QTFruit()"); engine.evaluate("res.fromJScript(eLedState.TriState)");   class QTFruit : public QObject {     Q_OBJECT  public:     enum eLedState { Off, On , TriState};     Q_ENUMS( eLedState )         QTFruit();     ~QTFruit();      QTFruit( const QTFruit & other );      //QTFruit(const QTFruit& other);  public slots:     void fromJScript(eLedState state);      //void on_inputSpinBox1_valueChanged(int value);      //void on_buttonClicked(); //   void fromJScript(); //private:  }; Q_DECLARE_METATYPE(QTFruit*) Q_DECLARE_METATYPE(QTFruit)  QScriptValue QTFruitConstructor(QScriptContext * /* context */,                             QScriptEngine *interpreter); 


回答5:

And the cpp:

QScriptValue QTFruitConstructor(QScriptContext * /* context */,                             QScriptEngine *interpreter) {     //return interpreter->toScriptValue(new QTFruit());     //or     return interpreter->toScriptValue(QTFruit()); //but then you need the public copy contructor  }   QTFruit::QTFruit( const QTFruit & other )  : QObject() { }   QTFruit::~QTFruit() { }  QTFruit::QTFruit() { }  void QTFruit::fromJScript(eLedState state) {     int t = 0; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!