2009-06-05 29 views
9

Tôi có một lớp là lớp con của QObject mà tôi muốn đăng ký làm loại meta. Các QObject documentation nói rằng các nhà xây dựng bản sao nên được tư nhân, nhưng QMetaType documentation nói rằng một loại nên có một nhà xây dựng mặc định công cộng, một xây dựng bản sao công cộng, và một destructor công cộng.Lớp con của QObject, qRegisterMetaType và hàm tạo bản sao riêng

Tôi có thể ghi đè lên hàm tạo bản sao riêng tư của QObject và khai báo hàm tạo bản sao công khai, nhưng đây có phải là an toàn/ok/phải không?

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

Con đường tôi đã kết thúc đi là sử dụng QSharedPointer (Qt 4.5 trở lên). Q_DECLARE_METATYPE (QSharedPointer ) – darkadept

Trả lời

16

Không an toàn để đặt công cụ tạo bản sao của QObject ở chế độ công khai. Tuy nhiên, bạn có thể đăng ký một con trỏ lớp làm kiểu biến. tức là:

Q_DECLARE_METATYPE (MyClass *);

Đó là cách Qt xử lý nó bằng QObject và QWidget.

5

Điều bạn đang yêu cầu hoàn toàn ổn. Bạn không thể sử dụng QObject s copy constructor (đó là tư nhân) trong việc thực hiện xây dựng bản sao của bạn, nhưng sau đó một lần nữa, không ai buộc bạn phải:

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

Tùy thuộc vào những dịch vụ bạn cần từ QObject, bạn cần để sao chép một số thuộc tính từ other, trong cả ctor bản sao và toán tử gán bản sao. Ví dụ: nếu bạn sử dụng tính năng QObject cho tính năng động, bạn cũng cần phải sao chép các tính năng đó:

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

Tương tự như vậy, nếu bạn muốn duy trì kết nối tín hiệu/khe.

+0

Đúng, có ý nghĩa. Vì vậy, nó có thể nhưng cần phải được mã hóa rất cẩn thận. – darkadept

0

Tôi sử dụng hàm copyValue(const MyClass & other) riêng biệt để sao chép các thành viên dữ liệu xác định "giá trị" của phiên bản MyClass. Điều đó đảm bảo rằng tôi không phá vỡ giả định của QObject danh tính duy nhất, trong khi vẫn có thể sao chép các phần của lớp được xác định tại thời gian biên dịch.

0
QTFruit fruit; 
QScriptValue scriptedFruitObject = engine.newQObject(&fruit); 
engine.globalObject().setProperty("fruit", scriptedFruitObject); 

engine.setDefaultPrototype(qMetaTypeId<QTFruit>(), 
           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); 
+0

Và cpp: QScriptValue QTFruitConstructor (QScriptContext */* context * /, Trình thông dịch QScriptEngine *) { \t // return interpreter-> toScriptValue (new QTFruit()); \t // hoặc \t trả lời phiên dịch-> toScriptValue (QTFruit()); // nhưng sau đó bạn cần contructor bản sao công } QTFruit :: QTFruit (const QTFruit & khác) : QObject() { } QTFruit :: ~ QTFruit() { } QTFruit: : QTFruit() { } void QTFruit :: fromJScript (trạng thái eLedState) { \t int t = 0; } –

0

Và 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; 
} 
+0

Chào mừng bạn đến với StackOverflow. Nếu bạn muốn thêm một cái gì đó vào câu trả lời trước đó của bạn, bạn có thể chỉnh sửa nó. Trong khi bạn đang ở đó, bạn cũng có thể muốn thêm một số lời giải thích cho mã của bạn. – void

Các vấn đề liên quan