【问题标题】:Is there any way to access a local variable in outer scope in C++?有没有办法在 C++ 中访问外部范围内的局部变量?
【发布时间】:2012-01-11 14:50:11
【问题描述】:

只是出于好奇:如果我有嵌套范围,就像在这个示例 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;

}

有没有办法从“中间”范围(既不是全局也不是本地)访问具有值2 的变量v

【问题讨论】:

  • 无论如何这在 C# 中是无效的。
  • 我会说这是一个相当糟糕的做法,在每个新范围内使用相同的变量名似乎不是一个好主意。
  • 没有。如果您需要访问它,请重命名变量。
  • 为了补充 Jon 的观点,一个本地 v 是合法的,但是 main 内的 second v 本地会产生问题,因为另一个 v 已经在“父级或current" 范围,正如编译器消息所说的那样。
  • @JonSkeet 好的,这不能用 C# 编译,我不知道。谢谢!

标签: c++ scope


【解决方案1】:

您可以像这样将新引用声明为别名

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

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

【讨论】:

  • 这样做的目的而不是简单地将v 重命名为vlocal 会是什么?
  • @Nim 如果 OP 担心以最小的改动更改一些意大利面条式遗留代码
【解决方案2】:

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

考虑到它必须被允许,它需要大量复杂的处理,想象一下有 n 个作用域(很可能是无限的)的情况并处理这些。

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

【讨论】:

  • 范围数无限的例子是什么?或者你只是想说一个非常多的范围?
  • 想象一下在一系列扩展类(可能是无限的)中有n个嵌套继承的成员函数的情况并处理这些。哦等等,有办法处理这些。我同意肯定有更合乎逻辑和更容易维护的做事方式,但你复杂的处理评论是无关紧要的
【解决方案3】:

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

#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 ();
}

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

希望对你有帮助!

【讨论】:

    【解决方案4】:

    你可以这样伪装:

    #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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      • 2011-08-23
      • 1970-01-01
      相关资源
      最近更新 更多