C ++继承:成员的范围和可见性

时间:2010-06-13 19:32:30

标签: c++ class inheritance redeclaration

你能解释为什么不允许这样做,

#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;
}

在这两种情况下,我们在a中都有一个名为class B的公共变量和一个私有变量。


现在编辑!

4 个答案:

答案 0 :(得分:15)

  

在这两种情况下,我们都有一个公众   和一个名为in的私有变量   B级。

不,那不是真的。

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

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

答案 1 :(得分:3)

因为B::a 在第二个示例中隐藏了 A::a。您仍然可以访问它,但它需要显式限定编译器,以确定您要求具有相同hame的父类成员。

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

答案 2 :(得分:0)

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

我也相信它归结为名称缩放:存储说明符不会作为实际名称的一部分结束。不过我可能错了。

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

在课堂上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)

}

}

答案 3 :(得分:0)

第一个示例中的B类无效,因为C ++无法通过其访问说明符(public / private / protected)区分成员。但是,名称空间是C ++区分成员的一种方式。在第二个代码中的B类中,您没有“公开”和“私有”,您有B::aA::a

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