繁体   English   中英

C ++中的范围和返回值

[英]Scope and return values in C++

我再次从c ++开始,正在考虑变量的范围。 如果我在函数内有一个变量,然后返回该变量,则返回该变量时,它所处的作用域是否已终止,该变量是否为“死”?

我已经尝试过使用返回字符串的函数来完成此操作。 谁能解释一下? 或者至少将我指向可以向我解释这一点的地方。

谢谢

该函数终止时,将发生以下步骤:

  • 该函数的返回值将被复制到为此目的而放在堆栈中的占位符。

  • 弹出堆栈框架指针之后的所有内容。 这会破坏所有局部变量和参数。

  • 返回值从堆栈中弹出,并被分配为该函数的值。 如果该函数的值未分配给任何对象,则不会发生分配,并且该值会丢失。

  • 下一条要执行的指令的地址从堆栈中弹出,CPU从该指令恢复执行。

堆栈和堆

这实际上取决于您要返回的变量类型。 如果返回原语,那么它是通过副本而不是引用返回的,因此该值将被复制到调用函数可以获取它的堆栈的顶部(或更常见的是放置到寄存器中)。 如果您在堆上分配一个对象或内存并返回一个指针,那么它不会死,因为它在堆上,而不是在堆栈上。 但是,如果您在堆栈上分配一些东西并返回它,那将是一件坏事。 例如,以下任何一个都非常糟糕:

int *myBadAddingFunction(int a, int b)
{
    int result;

    result = a + b;
    return &result; // this is very bad and the result is undefined
}

char *myOtherBadFunction()
{
    char myString[256];

    strcpy(myString, "This is my string!");
    return myString; // also allocated on the stack, also bad
}

返回值时,将进行复制。 局部变量的作用域结束了,但是创建了一个副本,并将其返回给调用函数。 例:

int funcB() {
  int j = 12;
  return j;
}

void A() {
  int i;
  i = funcB();
}

将j(12)的值复制并返回给i,这样我将收到12的值。

只是一些面向内存模型的解释:当调用一个函数时,会为该函数放置一个临时空间以放置其局部变量,称为frame 当函数(被调用方)返回其值时,它将返回值放入调用它的函数(调用方)的框架中,然后销毁被调用方框架。

“框架被破坏”部分就是为什么您不能从函数返回指针或对局部变量的引用。 指针实际上是一个内存位置,因此一旦销毁帧,返回局部变量(按照定义:帧内的变量)的内存位置就变得不正确。 由于被调用方帧一返回其值就被销毁,因此任何指向本地变量的指针或引用都是立即不正确的。

局部变量被复制到返回值。 对于非平凡的类,将调用复制构造函数。

如果返回指针或对局部变量的引用,您将遇到麻烦-就像您的直觉所建议的那样。

这取决于返回项目的类型。 如果按值返回,则将创建该变量的新副本以返回给调用方。 我想想,您不必担心对象的寿命,但是您可能需要担心复制对象的成本(但请不要过早优化-正确性更为重要):

std::string someFunc( std::string& const s)
{
    return s + "copy";
}

如果函数正在返回引用,则您需要注意所返回的内容,因为它的生存期需要延长到函数的生存期之外,并且如果您使用new来创建该函数,则调用者不一定能够delete它。宾语:

std::string& someFunc2( std::string const& s)
{
    return s + "reference to a copy";   // this is bad - the temp object created will 
                                        //  be destroyed after the expression the 
                                        //  function call is in finishes.
                                        //  Some, but not all, compilers will warn 
                                        //  about this.
}

当然,返回指针将具有类似的生命周期注意事项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM