0

我正在尝试为 qt 脚本编写示例代码。当我与复制构造器声明时,我认为我做的事情是正确的,QObjecy并且我还冒昧地声明了=操作员。但是这段代码一直给我

'QObject::QObject' : cannot access private member declared in class 'QObject'

错误。

我声明 a MyClasswhich is aQObject如下。我知道这样一个事实,有人可以看到我在这里做的事情。

标题:

#ifndef SCRIPT_CLASSES_H
#define SCRIPT_CLASSES_H
#include "QObject"
#include "QtScript/QScriptValue"
#include "QtScript/QScriptable"
#include "QtScript/QScriptClass"

class MyClass : public QObject
{
    Q_OBJECT
//    Q_PROPERTY( int _id WRITE setId READ id )
public :
    MyClass(QObject *aparent =0) ;
    ~MyClass();

//     bool operator =(MyClass obj);

public slots:
    void setId(int d);
    int id() const ;
//    bool MyClass::equals(const MyClass &other);
private :
    int _id;
};

class QScriptEngine;
class Script_Classes : public QObject, public QScriptClass
{
public:
    Script_Classes(QScriptEngine *engine);
    ~Script_Classes();
private :
    static QScriptValue myClassToScript(QScriptEngine *engine,const MyClass &in);
    static void myClassFromScript(const QScriptValue &object, MyClass &out);
};

#endif // SCRIPT_CLASSES_H

我的源类如下:

#include "script_classes.h"
#include "QMetaType"
#include "QtScript/QScriptEngine"
#include "QtScript/QScriptValue"

Q_DECLARE_METATYPE(MyClass)
Q_DECLARE_METATYPE(MyClass*)

MyClass::MyClass(QObject *aparent) : QObject (aparent){}

MyClass::~MyClass(){}

void MyClass::setId(int d){
    _id = d;
}


int MyClass::id() const{
   return _id;
}

bool MyClass::equals(const MyClass &other)
{
    return id() == other.id();
}

bool MyClass::operator =(MyClass obj){
    return id()==obj.id();
}



Script_Classes::Script_Classes(QScriptEngine *engine):QObject(engine),QScriptClass(engine)
{
    qScriptRegisterMetaType<MyClass>(engine, myClassToScript, myClassFromScript);
    MyClass testClass(this);
}

void Script_Classes::myClassFromScript(const QScriptValue &object, MyClass &out){
out.setId(object.property("id").toInt32());
}

QScriptValue Script_Classes::myClassToScript(QScriptEngine *engine, const  MyClass &in)    
{
    QScriptValue value = engine->newObject();
    value.setProperty("id", in.id());
    return value;
}
4

1 回答 1

8

问题是您无法复制QObject. 从QObject文档中:

QObject 既没有复制构造函数也没有赋值运算符。 这是设计使然。实际上,它们是被声明的,但是在一个带有宏 Q_DISABLE_COPY() 的私有部分中。事实上,所有从 QObject 派生的 Qt 类(直接或间接)都使用这个宏来声明它们的复制构造函数和赋值运算符是私有的。推理可以在 Qt 对象模型页面上关于 Identity vs Value 的讨论中找到。

主要结果是您应该使用指向 QObject(或指向您的 QObject 子类)的指针,否则您可能会试图将 QObject 子类用作值。例如,如果没有复制构造函数,就不能使用 QObject 的子类作为要存储在容器类之一中的值。您必须存储指针。

QObject没有==实现,所以你不能比较你的类的两个实例。

PS重载=运算符并使其像原来那样运行==有什么意义?这使您的代码变得模糊并且调试更加复杂。

编辑

假设您有以下简单的类继承自QObject

class A : public QObject
{
     Q_OBJECT
public:
     int anInt;
     double aDouble;
}

现在假设您想A在代码中的某处创建两个实例。

A a1;
A a2;

a1=a2由于QObject's =接线员不公开,因此拨打电话是非法的。为了实现数据的复制,您需要做的是手动进行:

a2.anInt = a1.anInt
a2.aDouble = a1.aDouble

另一方面,如果您使用指针,则指向同一个对象是完全合法的

A* a1 = new A;
A* a2 = new A;
a1 = a2;

现在两者a1和都a2指向相同的内存位置并具有相同的数据。如果你想拥有两个不同的对象,你可以创建一个构造函数,参数是指向对象的指针。对于我们的简单课程,您可以:

A::A(A* a)
{
   anInt = a->anInt;
   aDouble = a->aDouble;
}

现在它是合法的:

A a1;
A a2(&a1);

如果您想知道为什么QObject不允许赋值,请阅读 Object Model 文档的Identity vs Value部分。

于 2011-11-11T16:12:01.277 回答