考虑以下代码片段:
int test; //global variable
class Base
{
int test; //private member of Base
public:
void getit()
{
cin>>test;
}
};
class Derived: public Base
{
public:
void check()
{
test++; //neither access global test nor the member of Base
}
};
在上面的代码中,观察变量test
。它首先在全局声明,然后再在私有范围内的类中声明。
我的问题第一个问题是编译器如何允许对变量test
进行多次声明以及为什么不给出错误?
此外,当函数check()
尝试访问test
时,编译器会出错。我知道私有成员不是继承的,不能在课外访问,但是它们存在一个必须可访问的全局变量。
第二个问题是 test
内check()
是否存在于Base
类中的全局一个或一个?另外,如何访问全局test
?
答案 0 :(得分:3)
编译器如何允许变量测试的多个声明以及为什么不给出错误?
这是C ++范围规则的基本原则。从概念上讲,它与声明一个与全局变量同名的局部变量没什么不同。
全局命名空间中的test
与test
成员变量不冲突(尽管其中一个"隐藏"另一个?不合格的方式,因为会员在查询期间会优先考虑。)
这就是语言的设计方式,这是一件好事。
此外,当函数check()尝试访问测试时,编译器会给出错误。
要考虑的重要事项恰恰是错误是什么。它没有告诉你没有找到符号test
;它告诉你它找到了成员变量,并且你无法访问它。
这告诉您访问说明符不会影响可见性,只会影响辅助功能:
您的会员test
仍会隐藏全球test
,即使您无法访问。
要指定全局test
,您需要撰写::test
。
答案 1 :(得分:2)
答案 2 :(得分:1)
考虑以下示例
#include <iostream>
int x = 1;
int main()
{
std::cout << "x = " << x << std::endl;
int x = 2;
std::cout << "x = " << x << std::endl;
std::cout << "x = " << ::x << std::endl;
{
int x = 3;
std::cout << "x = " << x << std::endl;
std::cout << "x = " << ::x << std::endl;
}
std::cout << "x = " << x << std::endl;
std::cout << "x = " << ::x << std::endl;
}
在内部声明性区域中声明的任何名称都隐藏在封闭声明性区域中声明的相同名称。
至于你的例子,然后成员函数开始在声明它们的类的范围内寻找名称。
所以成员函数getit
void getit()
{
cin>>test;
}
开始在类的范围内寻找名称测试,实际上这个名称是在类中声明的。
对于功能检查,访问方法不会影响名称的搜索。 finction在其基类的范围内查找名称。由于此名称不可访问,编译器会发出错误。