如何按值返回`qObject'衍生的类

How to return a `QObject`-derived class by value?

本文关键字:何按值 返回 qObject      更新时间:2023-10-16

为了提高代码可读性,我想在一个函数中创建一个对象,然后通过值返回它(我让编译器任命优化内存的任务)。

如果我有常规班,我可以做以下操作:

MyClass myFunction01()
{
  MyClass theRegularObject;
  //do things
  return theRegularObject;
}

所以在我的代码中我可以做:

MyClass myObject = myFunction01();

但是,如果myClass是QoBject派生的QoBject(我们称其为qobjderivedClass),我会收到一个汇编错误:

QObjDerivedClass::QObjDerivedClass(const QObjDerivedClass &) : attempting to reference a deleted function.

我认为问题存在于QOBject既没有复制构造函数,也没有分配运算符QOBject Doc。

我认为解决方案是以下解决方案,但也许我错过了更好的解决方案?

1.在main中创建对象并传递对象作为对函数的引用

void myFunction01(CMyClass &theObj) {//do things}
//In my program
CMyClass myObj;
myFunction01(myObj);

2.创建功能内部的动态对象并返回指针(智能指针?)

QSharedPointer<CMyClass> myFunction01()
{
  QSharedPointer<CMyClass> p_theObj(new CMyClass);            
  //do things
  return p_theObj;
}
//At my program
QSharedPointer<CMyClass> p_myObj = myFunction01();
//When p_myObj goes out of scope the CMyClass object will be deleted.
//WARNING: Very important not to set a parent when we create the CMyClass object. 
//Otherwise, we will have problems due to double deletion.

有更好的/其他想法吗?

通过设计,切勿按值通过QObject

QT对象模型要求我们将QT对象视为身份,而不是值。值复制或分配;身份是克隆的...因此,Qobject和QObject的所有子类(直接或间接)具有其复制构造函数和分配运算符。(来源)

因此,您的原始示例本质上是错误的。相反,您应该与指针与QObject S(和QObject派生类)进行交互。

QT的标准实践是使用new在堆上分配对象。只要对象具有适当的父,它将自动破坏。

所有子对象均已删除。如果这些对象中的任何一个都在堆栈或全局上,则您的程序迟早会崩溃。(来源)

在这样的官方样本中可以看到这种做法。这些对象被明确分配在堆上,然后将清理(delete)留给父母处理。

因此总结:在堆上分配您的QObject衍生对象,然后通过指针将它们传递。

注意:如果您愿意使用智能销钉,则此答案可以很好地摘要。