有没有办法在C++中访问外部作用域中的局部变量?

问题描述 投票:0回答:4

只是出于好奇:如果我有嵌套作用域,就像这个示例 C++ 代码中那样

using namespace std;

int v = 1; // global

int main (void)
{
    int v = 2; // local
    {
        int v = 3; // within subscope
        cout << "subscope: " << v << endl;
        // cout << "local: " << v << endl; 
        cout << "global: " << ::v << endl;
    }
    cout << "local: " << v << endl;

    cout << "global: " << ::v << endl;

}

有没有办法从“中间”范围(既不是全局也不是局部)访问具有值

v
的变量
2

c++ scope
4个回答
22
投票

您可以将新引用声明为别名,如下所示

int main (void)
{
    int v = 2; // local 
    int &vlocal = v;
    {
        int v = 3; // within subscope
        cout << "local: " << vlocal  << endl; 
    }
}

但我会完全避免这种做法。我花了几个小时调试这样的构造,因为变量在调试器中显示为由于范围而更改,并且我无法弄清楚它是如何更改的。


9
投票

答案是否定的,你不能。
局部作用域中的变量会隐藏全局作用域中的变量,并且该语言提供了一种通过使用全局限定名称来访问全局变量的方法,就像您所做的那样。但 C++ 作为一种语言并不提供任何访问中间作用域变量的方法。

考虑到必须允许它需要大量复杂的处理,想象一下具有 n 个范围(很可能是无限的)的情况以及对这些范围的处理。

您最好重命名中间变量并使用那些更符合逻辑且易于维护的变量。


5
投票

C++ 中有两种类型的范围解析运算符 - 一元范围和类范围。没有函数作用域或“任何特定父作用域”解析运算符。一般来说,这使得无法解决您的问题,因为您无法引用匿名范围。但是,您可以创建别名、重命名变量,或者将其作为类的一部分,这当然意味着代码更改。在这种特殊情况下,这是我可以在不重命名的情况下为您提供的最接近的结果:

#include <iostream>

using namespace std;

int v = 1; // global

class Program
{
    static int v; // local

public:
    static int main ()
    {
        int v = 3; // within subscope
        cout << "subscope: " << v << endl;
        cout << "local: " << Program::v << endl; 
        cout << "global: " << ::v << endl;
    }
};

int Program::v = 2;

int main ()
{
    return Program::main ();
}

还有其他方法,比如确保变量没有被优化并且在堆栈上,然后你可以直接使用堆栈来获取你想要的变量的值,但我们不要这样做。

希望有帮助!


2
投票

你可以像这样伪造它:

#include <iostream>
using namespace std;
int v = 1;

int main()
{
        int v = 2;
        {
                int &rv = v; // create a reference
                int v = 3; // then shadow it

                cout << "subscope: " << v << endl;
                cout << "local: " << rv << endl;
                cout << "global: " << ::v << endl;
        }
        cout << "local: " << v << endl;

        cout << "global: " << ::v << endl;

        return 0;
}

有趣的是,它可以在 cygwin g++ 上编译,但如果您尝试运行它,则会出现段错误:

#include <iostream>
using namespace std;
int v = 1;

int main()
{
        int v = 2;
        {
                int &v = v;
                cout << "subscope: " << v << endl;
                // cout << "local: " << v << endl; 
                cout << "global: " << ::v << endl;
        }
        cout << "local: " << v << endl;

        cout << "global: " << ::v << endl;

        return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.