【发布时间】:2016-05-01 20:46:12
【问题描述】:
我知道这可能已经被问过了,并且我已经查看了其他答案,但我仍然无法完全理解。 我想了解以下两个代码之间的区别:
MyClass getClass(){
return MyClass();
}
和
MyClass* returnClass(){
return new MyClass();
}
现在假设我在 main 中调用这些函数:
MyClass what = getClass();
MyClass* who = returnClass();
-
如果我明白这一点,在第一种情况下,在 函数范围将有自动存储,即当你退出 函数的范围,它的内存块将被释放。还有,之前 释放这些内存,返回的对象将被复制到 我创建的“什么”变量。所以只会存在一份 物体。我说的对吗?
1a。如果我是对的,为什么需要 RVO(返回值优化)?
在第二种情况下,对象将通过动态存储进行分配,即它甚至会存在于函数范围之外。所以我需要在上面使用
delete。该函数返回一个指向此类对象的指针,因此这次没有复制,执行delete who将释放先前分配的内存。我(希望)正确吗?-
我也知道我可以这样做:
MyClass& getClass(){ return MyClass(); }然后在 main:
MyClass who = getClass();通过这种方式,我只是告诉“谁”是与函数中创建的对象相同的 对象。不过,现在我们已经超出了函数范围,因此该对象不一定不再存在。所以我认为应该避免这种情况以避免麻烦,对吗? (对于
MyClass* who = &getClass();这将创建一个指向局部变量的指针)。
额外问题:我假设在返回 vector<T>(例如,vector<double>)时,到目前为止所说的任何内容都是正确的,尽管我错过了一些内容。
我知道一个向量是在堆栈中分配的,而它包含的东西在堆中,但是使用vector<T>::clear() 足以清除这样的内存。
现在我想遵循第一个过程(即按值返回一个向量):当向量将被复制时,它包含的对象也将被复制;但退出函数范围会破坏第一个对象。现在我拥有了不包含在任何地方的原始对象,因为它们的向量已被破坏,并且我无法删除仍在堆中的此类对象。或者clear() 是自动执行的?
我知道我可能会在这些主题(特别是矢量部分)中存在一些误解,所以我希望你能帮助我澄清它们。
【问题讨论】:
-
sub 1a:需要 RVO,因为没有 rvo,对象将在 getClass 方法的堆栈上创建,然后在返回时必须调用复制构造函数将对象复制到调用函数。另外
MyClass* who = &getClass();将不起作用,因为 getClass 上的 & 将为您提供指向 getClass 的函数指针,而不是指向其返回值的指针/引用 -
嗯?您说“返回的对象将被复制到“what”变量中,这是正确的。所以这是两个对象(返回的对象和 what 变量)。 RVO 将其变成一个对象。
标签: c++ vector pass-by-reference pass-by-value pass-by-pointer