C++:范围

本文详细介绍了C++中的作用域,包括全局范围、命名空间范围、本地范围、类范围、语句范围和函数范围。此外,还讨论了如何通过在封闭块中声明相同名称来隐藏名称,以及如何在类名被隐藏的情况下访问它们。同时,解释了如何使用范围解析运算符来访问全局范围的名称。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

当你声明一个程序元素(例如类、函数或变量)时,它的名称只能 “查看”,并在程序的某些部分中使用。 名称在其中可见的上下文称为 " 作用域"。 例如,如果在函数内声明变量 x , x 则仅在函数体中可见。 它具有 本地范围。 你的程序中可能存在同名的其他变量;只要它们在不同的范围内,它们就不会违反一个定义规则,也不会引发错误。

对于自动非静态变量,范围还决定了在程序内存中创建和销毁它们的时间。

有六种范围:

全局范围 全局名称是在任何类、函数或命名空间外部声明的名称。 但是,在 c + + 中,即使这些名称都存在于隐式全局命名空间中。 全局名称的作用域从声明点扩展到在其中声明它们的文件的结尾。 对于全局名称,可见性也由用于确定名称在程序的其他文件中是否可见的 链接 规则来控制。

命名空间范围 在任何类或枚举定义或函数块外的 命名空间中声明的名称,在其声明点到命名空间的末尾可见。 命名空间可以在不同文件的多个块中定义。

本地范围 在函数或 lambda 中声明的名称(包括参数名称)具有本地范围。 它们通常称为 “局部变量”。 它们只能从其声明点到函数或 lambda 主体的末尾可见。 本地作用域是一种块范围,本文稍后将对此进行讨论。

类范围 类成员的名称具有类作用域,它在整个类定义中进行扩展,而不考虑声明点。 类成员可访问性由 public 、 private 和关键字进一步控制 protected 。 只能使用 (的成员选择运算符来访问公共或受保护成员 。 或 ->) 或指向成员的指针运算符 ( * 或 -> *) 。

语句范围 在、、或语句中声明的名称 for if while switch 直到语句块的末尾才可见。

函数范围标签具有函数范围,这意味着它在整个函数体中可见,即使在其声明点之前也是如此。 函数作用域使得可以在 goto cleanup 声明标签之前编写语句 cleanup 。

隐藏名称

可通过在封闭块中声明名称来隐藏该名称。 在下图中,在内部块中重新声明 i,从而隐藏与外部块范围中的 i 关联的变量。
在这里插入图片描述

块范围和名称隐藏

来自图中显示的程序的输出为:

i = 0
i = 7
j = 9
i = 0

备注

自变量 szWhat 被视为处于函数的范围内。 因此,它被当做就像已在函数的最外层块中声明一样。

隐藏类名

通过声明同一范围内的函数、对象或变量或枚举器,可以隐藏类名称。 但是,当使用关键字作为前缀时,仍可以访问类名 class 。

// hiding_class_names.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

// Declare class Account at global scope.
class Account
{
public:
    Account( double InitialBalance )
        { balance = InitialBalance; }
    double GetBalance()
        { return balance; }
private:
    double balance;
};

double Account = 15.37;            // Hides class name Account

int main()
{
    class Account Checking( Account ); // Qualifies Account as
                                       //  class name

    cout << "Opening account with a balance of: "
         << Checking.GetBalance() << "\n";
}

//Output: Opening account with a balance of: 15.37
备注
为调用类名称 () 的任何位置 Account ,都必须使用关键字类将其与全局范围的变量帐户区分开来。 当类名出现在范围解析运算符 (:😃 的左侧时,此规则不适用。 在范围解析运算符的左侧的名称始终被视为类名称。

下面的示例演示如何使用关键字声明指向类型对象的指针 Account class :

class Account *Checking = new class Account( Account );

Account初始值设定项中的 (在前面的语句中的括号) 包含全局范围; 它的类型为 double 。

备注

此示例中所示的标识符名称的重用被视为较差的编程样式。

隐藏具有全局范围的名称

可以通过在块范围内显式声明相同的名称来隐藏具有全局作用域的名称。 但是,可以使用范围解析运算符 () 来访问全局范围名称 :: 。

#include <iostream>

int i = 7;   // i has global scope, outside all blocks
using namespace std;

int main( int argc, char *argv[] ) {
   int i = 5;   // i has block scope, hides i at global scope
   cout << "Block-scoped i has the value: " << i << "\n";
   cout << "Global-scoped i has the value: " << ::i << "\n";
}

Output

Block-scoped i has the value: 5
Global-scoped i has the value: 7

该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处
本文章博客地址:https://blog.youkuaiyun.com/it_cplusplus/article/details/118107173

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值