如何按值返回`QObject`派生类?

时间:2017-03-10 14:51:43

标签: c++ qt

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

如果我有常规课程,我可以执行以下操作:

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

所以在我的代码中,我可以这样做:

MyClass myObject = myFunction01();

但是,如果MyClass是一个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.

有更好的/其他想法吗?

1 个答案:

答案 0 :(得分:1)

按照设计,QObject永远不应该按值传递。

  

Qt对象模型要求我们将Qt对象视为身份,而不是值。复制或分配值;克隆标识...因此,QObject和QObject的所有子类(直接或间接)都禁用了复制构造函数和赋值运算符。 (Source

因此,你原来的例子本质上是错误的。相反,您应该使用指针与QObject s(和QObject派生类)进行交互。

Qt的标准做法是使用new在堆上分配对象。只要对象具有适当的父级it will be destroyed automatically

  

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

这种做法可以在官方样本中看到,例如this。这些对象在堆上显式分配,并且清理(delete)留给父进程处理。

总结一下:在堆上分配你的QObject派生对象,并通过指针传递它们。

注意:如果您更愿意使用智能指针,this answer可以很好地总结Qt中内置的内容。