smi*_*dha 19 c++ return function
当函数(被调用者)向调用函数返回一个数量时,是按值还是按引用返回?
问题是我编写了一个函数,它在调用时构建了一个非常大的向量.我想通过常量引用将这个大向量返回给调用函数(在本例中main()),这样我就可以对它进行一些进一步的处理.
我有点怀疑,因为有人告诉我,当C++函数返回并终止时,与该函数关联的所有变量/内存都会被擦除干净.
struct node{
string key;
int pnum;
node* ptr;
}
vector< vector<node> > myfun1(/*Some arguments*/)
{
/*Build the vector of vectors. Call it V*/
return v;
}
int main(void)
{
a=myfun1(/* Some arguments */)
}
Run Code Online (Sandbox Code Playgroud)
Ben*_*igt 26
C++函数可以通过值返回,通过引用返回(但不通过引用返回本地变量),或通过指针返回(同样,不通过指针返回本地).
当按值返回时,编译器通常可以进行优化,使其与通过引用返回一样快,而不会出现悬空引用的问题.这些优化通常称为"返回值优化(RVO)"和/或"命名返回值优化(NRVO)".
调用者提供空向量(通过引用)的另一种方法,并让函数填充它.然后它不需要返回任何东西.
你绝对应该阅读这篇博文:想要速度?通过价值.
pae*_*bal 26
默认情况下,C/C++中的所有内容都按值传递,包括返回类型,如下例所示:
T foo() ;
Run Code Online (Sandbox Code Playgroud)
在C++中,类型通常被认为是值类型(即它们的行为类似int或double类型),如果对象的构造/破坏不是微不足道的话,额外的副本可能是昂贵的.
如果要通过引用或指针返回,则需要将返回类型更改为:
T & foo() ; // return a reference
T * foo() ; // return a pointer
Run Code Online (Sandbox Code Playgroud)
但在这两种情况下,您都需要确保返回后返回的对象仍然存在.例如,如果返回的对象在函数体中的堆栈上分配,则该对象将被销毁,因此其引用/指针将无效.
如果您无法保证返回后对象仍然存在,那么您唯一的解决方案是:
void foo(T & t) ;
这样,在函数内部,您可以t根据需要设置值,并在函数返回后获得结果.
现在,如果您有机会使用C++ 0x/C++ 11,即使用支持r值引用/移动语义的编译器,如果您的对象具有正确的构造函数/运算符(如果您的对象是从标准库,然后它没关系,然后额外的临时副本将被优化掉,你可以保持符号:
T foo() ;
Run Code Online (Sandbox Code Playgroud)
知道编译器不会生成不必要的临时值.
C++ 可以按引用或按值返回。如果要返回引用,则必须将其指定为返回类型的一部分:
std::vector<int> my_func(); // returns value
std::vector<int>& my_func(); // returns reference
std::vector<int> const& my_func(); // returns constant reference
Run Code Online (Sandbox Code Playgroud)
当函数返回时,在函数内部创建的所有局部(堆栈)变量都会被销毁。这意味着您绝对不应该通过引用或常量引用(或指向它们的指针)返回局部变量。如果您按值返回向量,它可能会在本地被销毁之前被复制,这可能会很昂贵。(称为“返回值优化”的某些类型的优化有时可以删除副本,但这超出了本问题的范围。判断优化是否会发生在特定代码段上并不总是那么容易。)
如果你想在函数内部“创建”一个大向量然后不复制就返回它,最简单的方法是将向量作为引用参数传递给函数:
void fill_vector(std::vector<int> &vec) {
// fill "vec" and don't return anything...
}
Run Code Online (Sandbox Code Playgroud)
另请注意,在最近批准的 C++ 标准(称为 C++0x 或 C++11)的新版本中,按值从函数返回本地向量实际上不会复制该向量,而是将其有效地移动到新版本中地点。执行此操作的代码看起来与C++ 以前版本中的代码相同,后者可能会被强制复制向量。检查您的编译器是否支持“移动语义”(C++11 标准中使这成为可能的部分)。