即使在声明了复制构造函数之后,QObject 也会返回异常
Posted
技术标签:
【中文标题】即使在声明了复制构造函数之后,QObject 也会返回异常【英文标题】:QObject retunrs with exception even after the copy constructor being declared 【发布时间】:2011-11-11 16:06:00 【问题描述】:我正在尝试为 qt 脚本编写示例代码。当我用复制构造器声明QObjecy
时,我认为我做对了,我还冒昧地声明了=
运算符。但是这段代码一直给我
'QObject::QObject' : cannot access private member declared in class 'QObject'
错误。
我声明一个MyClass
,它是一个QObject
,如下所示。我知道这样一个事实,有人可以看到我在这里做错了什么。
标题:
#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;
【问题讨论】:
【参考方案1】:问题是您无法复制QObject
。来自QObject
文档:
QObject 既没有复制构造函数也没有赋值运算符。 这是设计使然。实际上,它们是声明的,但是在私有的 带有宏 Q_DISABLE_COPY() 的部分。事实上,所有的 Qt 类 派生自 QObject(直接或间接)使用此宏声明 他们的复制构造函数和赋值运算符是私有的。这 在 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
不允许赋值,请阅读对象模型文档的 Identity vs Value 部分。
【讨论】:
您好,非常感谢您的快速回复。我仍然很困惑。你说“你应该使用指向 QObject 的指针”。我以为这就是我在声明“MyClass(QObject *aparent =0);”时所做的事情是不是。请告诉我,给我一个简单的例子,或者给我一个简单的例子。我试过用谷歌搜索,一切都和你的建议一样,但我不明白如何在实践中做到这一点。重载 = 是实现复制构造函数的绝望措施,因为它表示 QObject 中没有提供它。 我不知道该怎么感谢你。这不仅仅是一个帮助......非常感谢......以上是关于即使在声明了复制构造函数之后,QObject 也会返回异常的主要内容,如果未能解决你的问题,请参考以下文章