c++函数中动态分配大结构时的返回值选择

The return value choose when dynamically allocate a big structure in a function in C++

本文关键字:返回值 选择 结构 函数 动态分配 c++      更新时间:2023-10-16

输入function:

vector<MyClass>* My_func(int a)
{
    vector<MyClass>* ptr = new vector<MyClass>;
    //...... Add a lot of elements to this vector, and let's say MyClass is also relatively big structure.
    return ptr;
}

这个方法留给用户释放指针的责任。

我能想到的另一种方法是在函数中创建局部变量并返回值:
vector<MyClass> My_func(int a)
    {
        vector<MyClass> vec;
        //...... Add a lot of elements to this vector, and let's say MyClass is also relatively big structure.
        return vec;
    }

这种方法避免了用户的责任,但在返回和复制值时可能会占用大量空间。

也许智能指针在c++是一个更好的选择,但我不确定。我以前没有用过智能指针。人们遇到这种情况会怎么做?他们会选择什么样的返回类型?

谢谢你的提示:-)

在这种构造的大多数情况下,编译器将执行"返回值优化",这意味着它实际上并没有复制返回的数据结构,而是直接写入将返回到的位置的数据结构。

因此,您可以安全地这样做,而不必担心它被复制。

然而,另一种方法是不首先返回一个向量,而是请求调用代码传递一个:

比如:

 void My_func(int a, vector<MyClass>& vec)
 {
   ... 
 }

保证避免复制。

在许多情况下,返回值优化可以很容易地处理不必要的复制。问题是:你打算如何在函数外使用这个向量?如果你有这样的内容:

vector<MyClass> ret = My_func(a);

然后优化可以处理这个问题。

另一方面,如果你想重用一个现有的vector,你可以传递一个非const引用给一个现有的vector,但在很多情况下,这是不需要或有用的。

vector<MyClass> ret;
// do something with ret ...
My_func(a, ret);

另外,这也改变了你的函数的语义(例如,你可能需要clear()向量)。

下面是vector

的内部结构
template <typename T>
class vector {
private:
  size_t m_size;
  size_t m_cap;
  T * m_data;
public:
//methods push pop etc.
};

正如你所见,vector的大小(带有两个额外的size_t数据成员)并不比指针的大小大多少。传递向量而不是指针的性能优势可以忽略不计,事实上,使用指针访问向量会变慢,因为每次都必须解引用指针。一般不创建指向vector的指针。

同样,永远不要返回指向局部变量的指针。一旦返回值&本地变量的内存将被清除。超出方法的作用域。理想情况下,在调用方法My_func时,应该在调用函数中创建一个vector,并传递对vector的引用。