2010-06-13 106 views
5

你能解释为什么这是不允许的知名度,C++继承:确定范围和成员

#include <stdio.h> 

class B { 
private: 
    int a; 
public: 
    int a; 
}; 

int main() { 
    return 0; 
} 

,而这是什么?

#include <stdio.h> 

class A { 
public: 
    int a; 
}; 

class B : public A{ 
private: 
    int a; 
}; 

int main() { 
    return 0; 
} 

在这两种情况下,我们有一个公开和class B命名a一个私有变量。


现在编辑!

+0

@尼尔:你的意思是第二个声明一个A类? – Alan 2010-06-13 19:37:33

+1

@Alan是的 - 我对这个问题感到困惑,我有点困惑:-) – 2010-06-13 19:38:31

+3

为什么这有一个downvote?这是一个合理的问题,我记得在C++中学习类时想知道同样的事情...... – Cam 2010-06-13 19:39:19

回答

15

在这两种情况下,我们有一个名为公共 和一个私有变量在 B类

不,那不是真的。

在第一种情况下,在同一范围内不能有两个具有相同名称的标识符。而在第二种情况下,B::a隐藏A::a,并访问A::a你必须完全限定名称:在第一实例中

b.a = 10; // Error. You can't access a private member. 
b.A::a = 10; // OK. 
0

第一个是不允许的,因为它会导致模糊的定义。在第二种情况下,尽管你有一个公开的和一个私人的a整数变量,但是你已经在B类中隐藏了A :: a。编译器隐式知道你想要什么,因为有一种方法可以显式访问隐藏的变量。

我也相信它归结为名称mangaling:存储说明符不会最终成为实际名称的一部分。不过,我可能会错。

说明为什么允许一个以及为什么另一个不允许的最简单方法是查看编译器如何编译使用每个变量的成员函数。

内,您的B类:

class b { 

int a; 
public: 
int a; 

void myMethod() 
{ 
a = 10; //what a should the compiler use? Ambiguous, so the compiler sez BZZT. 
} 

} 

对于第二个例子:

class A 
{ 
public: 
int a; 
} 

class B: public A 
{ 
private: 
int a; 

void someMethod() 
{ 
a = 10; //implied that you are using B::a (which may be a programmer error) 

} 

} 
+0

对不起。现在编辑! – Moeb 2010-06-13 19:45:52

3

因为B::a隐藏在第二个例子中A::a。您仍然可以访问它,但它需要编译器的明确资格来确定您要求父类的成员具有相同的耻辱。

在第一个示例中,两个a都在相同的范围内,而在第二个示例中,范围不同。

0

B类是无效的,因为C++不能区分可以通过访问说明成员(公共/私人/保护)。但是,名称空间是C++区分成员的一种方式。在第二个代码中的B类中,您没有“公共a”和“私人a”,您有B::aA::a

即使声明具有不同访问说明符的相同名称/签名的成员是允许的,也无法解决正确的成员。