繁体   English   中英

从函数返回const对局部变量的引用

[英]Returning const reference to local variable from a function

我有一些关于从函数返回对局部变量的引用的问题:

class A {
public:
    A(int xx)
    : x(xx)
    {
        printf("A::A()\n");
    }
};

const A& getA1()
{
    A a(5);
    return a;
}

A& getA2()
{
    A a(5);
    return a;
}

A getA3()
{
    A a(5);
    return a;
}

int main()
{
    const A& newA1 = getA1(); //1
    A& newA2 = getA2(); //2
    A& newA3 = getA3(); //3
}

我的问题是=>

  1. getA1()的实现是否正确? 我觉得这是不正确的,因为它返回局部变量的地址或临时变量。

  2. main (1,2,3)中哪些语句会导致未定义的行为?

  3. const A& newA1 = getA1(); 标准是否保证const引用的临时绑定在引用超出范围之前不会被销毁?

1. getA1()实现是否正确? 我觉得这是不正确的,因为它返回本地变量或临时的地址。

你的程序中getA3()正确的getAx()版本是getA3() 无论你以后如何使用它们,其他两个都有不确定的行为。

2.主要(1,2,3)中的哪些陈述会导致未定义的行为?

从某种意义上说,没有一个。 对于1和2,未定义的行为是函数体的结果。 对于最后一行, newA3应该是编译错误,因为您不能将临时绑定到非const引用。

3.在const A& newA1 = getA1(); 标准保证在引用超出范围之前,不会销毁由const引用临时绑定的内容吗?

不。以下是一个例子:

A const & newConstA3 = getA3 ();

这里, getA3()返回一个临时值,该临时值的生命周期现在绑定到对象newConstA3 换句话说,临时将存在,直到newConstA3超出范围。

Q1:是的,这是一个问题,请参阅Q2的回答。

Q2:1和2是未定义的,因为它们引用了getA1和getA2堆栈上的局部变量。 这些变量超出范围并且不再可用,并且随着堆栈不断变化,可能会覆盖更糟糕的变量。 getA3起作用,因为创建了返回值的副本并将其返回给调用者。

问题3:对于Q2的回答,没有这样的保证。

我认为主要的问题是你根本不回归临时工,你应该这样做

return A(5);

而不是

A a(5);
return a;

否则,您将返回本地变量地址,而不是临时变量。 而临时的const引用仅适用于临时工。

我认为它在这里解释: 临时到const引用

如果您将在VC6上编译它,您将收到此警告

******编译器警告(级别1)C4172返回局部变量或临时的地址函数返回局部变量或临时对象的地址。 函数返回时会破坏局部变量和临时对象,因此返回的地址无效。

在测试这个问题时,我发现有趣的事情(给定的代码在VC6中工作):

 class MyClass
{
 public:
 MyClass()
 {
  objID=++cntr;
 }
MyClass& myFunc()
{
    MyClass obj;
    return obj;
}
 int objID;
 static int cntr;
};

int MyClass::cntr;

main()
{
 MyClass tseadf;
 cout<<(tseadf.myFunc()).objID<<endl;

}

暂无
暂无

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

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