5

Can you explain why this is not allowed,

#include <stdio.h>

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

int main() {
    return 0;
}

while this is?

#include <stdio.h>

class A {
public:
    int a;
};

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

int main() {
    return 0;
}

In both the cases, we have one public and one private variable named a in class B.


edited now!

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
Moeb
  • 10,527
  • 31
  • 84
  • 110
  • @Neil: You mean the 2nd one declares a Class A? – Alan Jun 13 '10 at 19:37
  • 1
    @Alan Yes - I was so bemused by the question I got a bit confused :-) –  Jun 13 '10 at 19:38
  • 3
    Why does this have a downvote? It's a reasonable question, I remember wondering the same thing while learning classes in C++... – Cam Jun 13 '10 at 19:39
  • This seems more like a question than a doubt. Do you lack confidence in C++'s inheritance? – Thanatos Jun 13 '10 at 19:42
  • @incrediman The downvotes were for the question before the OP edited it, completely changing its sense. –  Jun 13 '10 at 19:43
  • possible duplicate of [Is there any difference these two pieces of code?](http://stackoverflow.com/questions/3033405/is-there-any-difference-these-two-pieces-of-code) – Edward Strange Jun 13 '10 at 19:47
  • @Thanatos a large number of non-English users of the English language make minor errors. One of the south Asian languages has different shades between 'question' and 'doubt' so it's very common to find posts which have the wrong use. – Pete Kirkham Jun 13 '10 at 19:52
  • @Noah: They're different, but related. – Donal Fellows Jun 13 '10 at 19:52
  • @Thanatos @Pete: Edited title to be clearer; on this site “question” is a bit of a null phrase (even if written as “doubt”). – Donal Fellows Jun 13 '10 at 19:56

4 Answers4

15

In both the cases, we have one public and one private variable named a in class B.

No, thats not true.

In the first case, you can't have two identifiers with the same name in the same scope. While in the second case, B::a hides A::a, and to access A::a you have to fully qualify the name:

b.a = 10; // Error. You can't access a private member.
b.A::a = 10; // OK.
Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
3

Because B::a hides A::a in the second example. You can still access it, but it needs explicit qualification for the compiler to figure out you are asking for the member of parent class with the same hame.

In the first example both a's are in the same scope, while in the second example the scopes are different.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
0

The first isn't allowed because it leads to ambiguous definitions. In the 2nd, although you do have both a public and a private a integer variable, you've hidden A::a inside your B class. The compiler knows implicitly what you want because there is a way to explicitly access a hidden variables.

I also believe that it boils down to name mangaling: storage specifiers don't end up as part of the actual name. I could be wrong on this however.

The easiest way to illustrate why one is allowed and why the other isn't is to look at how the compiler would compile a member function that uses each variable.

Inside your class b:

class b {

int a;
public:
int a;

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

}

For the 2nd example:

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)

}

}
Alan
  • 45,915
  • 17
  • 113
  • 134
0

Class B in the first example is not valid because C++ cannot distinguish members by their access specifiers (public/private/protected). However, namespaces are a way for C++ to distinguish members. In class B in the second code you don't have a "public a" and a "private a", you have B::a and A::a.

Even if declaring members of the same name/signature with different access specifiers was allowed, there would be no way to address the correct member.

tiftik
  • 978
  • 5
  • 10