C++ C+中的函数+;按值返回还是按引用返回?

C++ C+中的函数+;按值返回还是按引用返回?,c++,function,return,C++,Function,Return,当函数(被调用方)向调用方函数返回数量时,是否由 价值还是参照 问题是我写了一个函数,它在调用时构建了一个非常大的向量。我想通过常量引用将这个大向量返回给调用函数(在本例中为main()),以便对其进行进一步处理 我怀疑,因为我被告知,当C++函数返回并终止时,与该函数相关联的所有变量/内存都会被擦除干净。p> struct node{ string key; int pnum; node* ptr; } vector< vector<node> > myfun1(/

当函数(被调用方)向调用方函数返回数量时,是否由 价值还是参照

问题是我写了一个函数,它在调用时构建了一个非常大的向量。我想通过常量引用将这个大向量返回给调用函数(在本例中为
main()
),以便对其进行进一步处理

我怀疑,因为我被告知,当C++函数返回并终止时,与该函数相关联的所有变量/内存都会被擦除干净。p>

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 */)
}
struct节点{
字符串键;
int pnum;
节点*ptr;
}
vectormyfun1(/*一些参数*/)
{
/*建立向量的向量,称之为V*/
返回v;
}
内部主(空)
{
a=myfun1(/*一些参数*/)
}

堆栈上定义的所有变量在退出时都会被清除。 要返回一个变量,您应该在堆上分配它,这是使用new关键字(或malloc)完成的


类和结构作为指针传递,而基元类型作为值传递。

C++函数可以通过值、引用(但不通过引用返回局部变量)或指针(同样,不通过指针返回局部变量)返回

当按值返回时,编译器通常可以进行优化,使其与按引用返回一样快,而不会出现挂起引用的问题。这些优化通常称为“返回值优化(RVO)”和/或“命名返回值优化(NRVO)”

另一种方法是让调用者提供一个空向量(通过引用),并让函数填充它。那么它就不需要返回任何东西了


你肯定应该读一下这篇博文:

它是由你声明的返回类型返回的<代码>向量f()
向量&f()分别按值和引用返回。但是,返回对函数中局部变量的引用将是一个严重错误,因为当函数作用域退出时,它将被吹走


有关如何有效地从函数返回大向量的好提示,请参见(事实上,此函数可以说是该函数的副本)。

函数将返回您告诉它返回的内容。如果要返回
向量
,则调用者会将其复制到变量hold中。除非通过const引用捕获该结果,否则不需要复制它。有一些优化允许函数通过将结果放在保存返回值的对象中来避免这种额外的副本构造。在更改性能设计之前,您应该阅读以下内容:


C++可以通过引用或值返回。如果要返回引用,必须将其指定为返回类型的一部分:

std::vector<int> my_func(); // returns value
std::vector<int>& my_func(); // returns reference
std::vector<int> const& my_func(); // returns constant reference
// Return by pointer (*)
T* f();

// Return by reference (a single '&')
T& f();
std::vector my_func();//返回值
std::vector&my_func();//返回引用
std::vector const&my_func();//返回常量引用
函数返回时,函数内部创建的所有局部(堆栈)变量都将被销毁。这意味着您绝对不应该通过引用或常量引用(或指向它们的指针)返回局部变量。如果按值返回向量,则可能会在销毁本地向量之前复制该向量,这可能代价高昂。(称为“返回值优化”的某些类型的优化有时可以删除副本,但这超出了本问题的范围。要判断优化是否会发生在特定的代码段上并不总是容易的。)

如果要在函数内部“创建”一个大向量,然后在不复制的情况下返回它,最简单的方法是将该向量作为参考参数传递给函数:

void fill_vector(std::vector<int> &vec) {
    // fill "vec" and don't return anything...
}
// Return by 'parameter' (a logical reference return)
void f(T& output);
void fill_向量(标准::向量和向量){
//填写“vec”并且不返回任何内容。。。
}

还注意到,在最近批准的C++标准新版本(称为C++ 0x或C++ 11)中,从函数返回值的局部向量实际上不会复制向量,它将被有效地移动到其新位置。这样做的代码看起来与以前版本的C++代码相同,这可能会强制复制向量。检查编译器是否支持“移动语义”(C++11标准中使之成为可能的部分)。

默认情况下,C/C++中的所有内容都按值传递,包括返回类型,如下例所示:

T foo() ;
在C++中,类型通常被认为是值类型(即它们的行为类似于<代码> int <代码>或<代码>双类型),如果对象的构造/破坏不是微不足道的,则额外的副本可能是昂贵的。 使用C++03 如果要通过引用或指针返回,则需要将返回类型更改为:

T & foo() ;  // return a reference
T * foo() ;  // return a pointer
但在这两种情况下,都需要确保返回的对象在返回后仍然存在。例如,如果返回的对象是在函数体的堆栈上分配的,则该对象将被销毁,因此,其引用/指针将无效

如果无法保证返回后对象仍然存在,则唯一的解决方案是:

T & foo() ;  // return a reference
T * foo() ;  // return a pointer
  • 接受额外副本的费用,并希望
  • 而是通过引用将变量作为参数传递给函数,如下所示:
  • void foo(T&T)

    这样,在函数内部,您可以根据需要设置
    t
    值,函数返回后,您就可以得到结果

    使用C++11 现在,如果您有机会使用C++0x/C++11,也就是说,使用支持的编译器,如果您的对象具有正确的构造函数/运算符(如果您的对象来自标准库,则可以),那么额外的临时副本将被优化掉,并且您可以保留符号:

    T foo() ;
    

    知道编译器不会生成不必要的临时值。

    < P>就像C++中的大多数东西一样,答案是“这取决于你如何定义函数”。