我认为C ++会将相同的特殊规则应用于static const
整数类型 ,无论 是否在命名空间范围内声明或声明在类/结构/联合中。
现在我想我已经被不合规的编译器教给了Bad Things。
static const int A = 1;
struct s
{
static const int A = 1;
};
除了范围明显不同之外,A
和s::A
的区别如何?
我特别好奇C ++ 03。
答案 0 :(得分:6)
关键字static
在类范围内并不意味着相同
并在命名空间范围内。实际上,它在命名空间范围内的用途是
弃用。
在类范围内声明变量时,static
表示
将有一个变量的单个实例,带有static
储存期限和寿命。课堂上的宣言
不是定义;如果变量使用,则必须是
在一个(只有一个)翻译单元中定义;如果不是
定义,你有未定义的行为。 (在实践中,取决于
在使用上,要么一切都会正常,否则你会得到一个
来自链接器的错误。)注意,如果声明是为了
一个const
整数类型,并包含一个初始化,它是
not 如果在需要的上下文中使用,则被视为已使用
一个常量积分表达式(如C风格的维度)
数组)。最简单和最可靠的事情就是定义它
某处。
在命名空间范围内声明变量时,static
表示
名称有内部联系,而不是外部;同
或者没有static
,声明是一个定义(所以那里
程序中应该没有其他定义)。在C ++ 03中,这个
使用已被弃用;请改用未命名的命名空间。请注意
如果变量本身是const
(顶级const),那么
它默认具有内部链接,因此static
没有
任何影响。 (如果您需要const
变量
外部链接,使其成为类成员或定义它
明确extern
,使用初始化程序来实现它
定义,而不仅仅是声明。)
答案 1 :(得分:0)
A
和s::A
有何不同?
最大的区别是A
的声明也是一个定义,而s::A
的声明则不然。我不确定你的“特殊规则”是什么意思,但static
在每种情况下都有不同的含义。
在命名空间范围内,它为其提供内部链接,以便在当前翻译单元外部看不到该对象。请注意,static
在这里是多余的,因为命名空间范围内的常量变量默认具有内部链接。
在类范围内,这意味着只有一个对象独立于类的任何实例化。
当他们的用法被替换为他们的字面值?
由于两者都是声明中具有初始化的整数常量,因此两者都可以在常量表达式中使用,并且编译器能够用编译时常量替换它们的值。
或许更合适的问题是,何时需要定义?
在C ++ 11中,如果变量是 odr-used 则需要它 - 粗略地说,如果你做任何需要变量的地址而不是它的值的东西。
在C ++ 03中,我认为如果完全使用该变量则需要它,虽然不需要诊断,如果你只使用它的值,许多编译器都不会抱怨。我可能错了;旧的规则相当复杂,我很高兴现在能够忘记它们。
什么时候可以拿到它的地址?
这要求变量在C ++ 03和C ++ 11中都有定义。该定义为变量分配存储空间,以便它具有地址。
当我需要单独定义它们时?
命名空间范围内的变量声明也是一个定义,除非您声明它extern
;所以你的第一个变量不需要单独的定义。
类范围内的变量声明不是定义;所以你的第二个变量在C ++ 03中需要一个单独的定义,如果它是 odr-used ,则在C ++ 11中需要。