我知道这可能已被问及我已经通过其他答案看过,但我仍然无法完全得到它。 我想了解以下两个代码之间的区别:返回一个对象:值,指针和引用
MyClass getClass(){
return MyClass();
}
和
MyClass* returnClass(){
return new MyClass();
}
现在,让我们说,我把这种功能在主:
MyClass what = getClass();
MyClass* who = returnClass();
如果我明白了,在第一种情况下,在 函数范围中创建的对象将具有自动存储器,即当你退出功能的范围时,其存储器块将被释放。另外,在释放这样的内存之前,返回的对象将被复制到 我创建的“what”变量中。所以将只存在一个 对象的副本。我对么?
1a。如果我是正确的,为什么需要RVO(返回值优化)?
在第二种情况下,该对象将通过动态存储器分配,即它甚至会存在于功能范围之外。所以我需要在其上使用
delete
。该函数返回一个指向这样的对象的指针,所以这次没有复制,并且执行delete who
将释放先前分配的内存。我(希望)正确吗?而且我知道我可以做这样的事情:
MyClass& getClass(){ return MyClass(); }
,然后在主:
MyClass who = getClass();
这样我只是告诉那个“谁”是与在函数中创建的对象相同的对象。但是,现在我们已经超出了函数范围,因此该对象不一定再存在。所以我认为这应该避免,以避免麻烦,对吗? (并且
MyClass* who = &getClass();
这将创建一个指向本地变量的指针)。
奖金的问题:我认为任何东西说,直到返回时vector<T>
(比方说,例如,vector<double>
)现在也是如此,虽然我错过了一些碎片。 我知道一个向量是在堆栈中分配的,而它包含的东西在堆中,但使用vector<T>::clear()
就足以清除这样的内存。 现在我想遵循第一个过程(即通过值返回一个向量):当向量将是复制时,它所包含的对象也将被复制;但退出功能范围会破坏第一个对象。现在我拥有了无处包含的原始对象,因为它们的向量已被销毁,我无法删除仍在堆中的这些对象。或者自动执行clear()
?
我知道我可能会在这些主题(特别是在矢量部分)中误解一些误解,所以我希望你能帮助我澄清它们。
子1A:需要RVO因为没有静脉阻塞的对象将在的getClass方法堆栈中创建,然后在返回的拷贝构造函数将被调用的对象复制到调用函数的栈。另外'MyClass * who =&getClass();'不会工作,因为getClass上的&会让你得到一个指向getClass的函数指针,而不是它的返回值的指针/引用 –
咦?你说“返回的对象将被复制到”what“变量中,这是正确的。这是两个对象(返回的对象和什么变量)。 RVO将其变成一个对象。 –