为了提高代码可读性,我想在函数内创建一个对象并按值返回它(我让编译器承担优化内存的任务)。
如果我有常规课程,我可以执行以下操作:
MyClass myFunction01()
{
MyClass theRegularObject;
//do things
return theRegularObject;
}
Run Code Online (Sandbox Code Playgroud)
所以在我的代码中我可以这样做:
MyClass myObject = myFunction01();
Run Code Online (Sandbox Code Playgroud)
但是,如果 MyClass 是 QObject 派生类(我们称之为 QObjDerivedClass),我会收到编译错误:
QObjDerivedClass::QObjDerivedClass(const QObjDerivedClass &) : attempting to reference a deleted function.
Run Code Online (Sandbox Code Playgroud)
我认为问题在于 QObject 既没有复制构造函数也没有赋值运算符QObject Doc。
作为可能的解决方案,我认为有以下几种,但也许我缺少更好的解决方案?
1.在main中创建对象并将该对象作为函数的引用传递
void myFunction01(CMyClass &theObj) {//do things}
//In my program
CMyClass myObj;
myFunction01(myObj);
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
还有更好/其他的想法吗?
根据设计,aQObject永远不应该按值传递。
Qt 对象模型要求我们将 Qt 对象视为身份,而不是值。值被复制或赋值;身份被克隆...因此,QObject 和 QObject 的所有子类(直接或间接)都禁用了其复制构造函数和赋值运算符。(来源)
因此,你原来的例子本质上是错误的。相反,您应该使用指针与QObjects (和QObject派生类)进行交互。
Qt 的标准做法是使用在堆上分配对象new。只要该对象有合适的父对象,它就会自动销毁。
所有子对象都被删除。如果这些对象中的任何一个位于堆栈或全局中,那么您的程序迟早会崩溃。(来源)
这种做法可以在官方示例中看到,比如这个。这些对象被显式地分配在堆上,并且清理(delete)留给父级来处理。
总结一下:QObject在堆上分配派生对象并通过指针传递它们。
注意:如果您更愿意使用智能指针,这个答案对 Qt 中内置的指针进行了很好的总结。