c++中的重声明过程是什么?



来自c++ ISO草案2020,6.2,第一段:

声明(条款9)可能会引入一个或多个名称翻译单元或重新声明前面介绍的名称声明。如果是,则声明指定解释和这些名称的语义属性。

重声明是否只在所有语义属性相同时发生,或者只需要相同的名称?

int main() {
int a = 12;
{
char a;
}
}

在上面的代码中,圆角括号内发生了什么?声明还是再声明?在下面的代码中,是否有声明或重新声明?:

int main() {
int a = 12;
{
int a ;
}
}

在这两种情况下,变量a的内部声明隐藏了a外部变量。因此,如果您以任何方式在内部块中使用变量a,那么它将引用内部a

例如,如果将第一个大小写修改为:

int a = 12;
{
char a;
decltype(a) p;//p is a char type instead of int
}

则变量p的类型是char而不是int。这是因为正如我所说,当你写decltype(a)时,括号内的a指的是内部变量a,而不是外部变量a,即a的内部声明隐藏了外部a。由于内部a的类型是char,所以p的类型将是char

现在让我们将示例2修改如下:

int a = 12;
{
int a  = 15;
std::cout<<a <<std::endl;//this will print 15 
}

在这种情况下,a的内部声明(也是一个定义)隐藏了外层a。所以当我们写std::cout<<a;时,我们指的是内部的a,它的值是15。我们会在屏幕上看到15个。同样,a的内部声明隐藏了a的外部声明。

变量或函数的声明只是声明它们存在于程序的某个地方,并指定确切的类型。这与定义不同,实际上是为变量或函数分配存储空间。

似乎是"重新声明";在c++中的某些情况下是有效的。下面是一个有效的重新声明的例子:

// file1.c
int Count;
// file2.c
void foo(void) {
extern int Count;
Count++;
}

你的两个例子都不是重新声明。它们只是声明一个新的局部变量,该局部变量与外部作用域中的另一个局部变量具有相同的名称。内部局部变量遮蔽(隐藏)外部变量。如果你没有引入了一个新的范围{}a会被重新定义。

两个变量同时存在,内部变量的生命周期包含在外部变量的生命周期中。在内部作用域结束时,内部变量的生命周期将结束,外部变量可以很容易地再次被访问。

您可以通过下面的小示例清楚地看到这一点:

struct A {
A() { cout << "Object being createdn"; }
~A() { cout << "Object being destroyedn"; }
};
void main() {
A a1; 
cout << "Beginning inner scopen";
{
A a1;
}
cout << "End of inner scopen";
}

在c++(以及C和Java和其他)中,在多个作用域中使用相同的名称是合法的-一些编译器(例如gcc - wshadow)可能会对此产生警告,因为它可能导致混淆。

最新更新