单定义规则与作用域

作用域描述了名称在文件多大范围内可见。C++ primer plus中还有一个定义是链接性,链接性描述了名称如何在不同文件间共享。其实我个人理解,链接性跟作用域描述的概念差不多,只不过一个是对文件内部可见性(访问)的描述,一个是对文件之间可见性(访问)的描述。

单定义规则,根据网上大部分的描述是,任何变量都只能定义一次,比如定义了int a,不能再重新定义一个int a,只能赋值。这显然是不严谨的,因为我们可以在不同的函数中定义同名的变量。

应该说,任何时候都只能存在一个相对可见的定义。

首先我们先来分析一下各种变量的作用域。

1、自动变量。如果在代码块中定义了变量,则该变量的存在时间和作用域都被限制在了该代码块内,该变量没有链接性。并且,在该代码块内,该变量会隐藏其他在代码块外部定义的同名变量。也就是说在该代码块内部,只有内部的定义是可见的,在代码块外部,只有外部的定义是可见的,所以,在代码块内部定义同名变量并不会违反单定义规则。

2、静态持续变量。静态持续变量的存在时间为整个程序执行期间,但是它的作用域和链接性取决于定义方式,定义方式有如下三种:

2.1、如果在所有函数外面定义一个变量,例如

//file1.cpp
int a;
int main()
{
return 0;
}

那么a就是一个全局变量,它的作用域为全文件,链接性为外部,也就是说它在其他的文件中也能共享(可见),只要加一个extern声明就行。

如果是这样的定义方式的话,那么在程序的其他文件中,也就是它的可见范围内,就不能在定义一个跟他同名的全局变量了。

2.2、如果采用下面这种方式在所有的函数外面定义一个变量,例如

//file2.cpp
static int a;
int main()
{
return 0;
}
那么a是一个静态全局变量,它的作用域为全文件,链接性为内部,也就是说它在其他文件中不能共享(不可见)。那么file1和file2一起编译,会不会出现错误呢?答案是不会,就像局部变量会在自己的代码块中隐藏外部的同名变量一样,file2中的a也会隐藏file1中的全局变量a的定义。在file2中,只有该文件中定义的a可见,而在其他文件中,file2中的a是不可见的,只有file1中的全局变量a可见。因此我们上面也说了,不能对全局变量定义两次(不能定义两个同名的全局变量)。

2.3、如果是在代码块中定义的静态局部变量,那么除了存在时间,它的行为跟局部变量是一样的。


关于函数,和变量一样,函数也有链接性。和c语言一样,c++不允许在一个函数的内部定义另一个函数,因此,所有函数的持续性都是静态的,即在程序执行期间都是存在的。默认情况下,函数的链接性为外部,即可以在文件间共享(可见)。还可以像变量一样,使用static将函数的链接性设置为内部,使之只能在一个文件中使用。必须同时在函数原型和函数定义前加上关键字static。这意味着该函数只在这个文件是可见的,还意味着可以在别的文件中定义一个跟他同名的函数。

所以,单定义规则严格来说应该是,只有一个相对可见的定义


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值