views:

109

answers:

2
#include<stdio.h>

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

int main(){
    B b;
    printf("%d", b.a);
    return 0;
}

#include<stdio.h>

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

int main(){
    B b;
    printf("%d", b.a);
    return 0;
}

I ask because I get different errors:

error: 'int B::a' is private

error: 'int A::a' is inaccessible

Apart from what the errors might reveal, is there any difference at all in the behaviour of these two pieces of code?

+2  A: 

They are different. In the first instance, you are creating two instances of the variable 'a'. One in the base class, one in the child class. In both examples you can't get access to the variable.

If you have:

A *pA = new B();
pA->a; // This will refer to A::a, which is allowed as it was defined public.

B *pB = new B();
pB->a; // This will refer to B::a, which you can't get access to.

If you want to hide access to the 'a' variable, I suggest the second example, using private inheritance. Be aware that private inheritance will also make any functions defined in the base class private.

Mark Ingram
In second example also, because of private inheritance, `a` will be there, but not accessible. so, whats the difference?
Amoeba
@Poiuyt : There are several differences, one obviously being the declaration, and some of which Mark pointed out. Maybe you need to clarify what you mean by "what's the difference?".
Stephen
@Poiuyt: In the first example, it's not the same `a`. It's a different `a` that's masking `A::a`.
Andrew Coleson
+2  A: 

In your first example, class B has two members named a, the one that it inherits from class A and the one that it defines itself. An object of class B ends up being larger as a result, and you can still access class A's a member explicitly:

#include <stdio.h>

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

int main()
{
    A a;
    B b;
    printf("sizeof(a) == %d, sizeof(b) == %d\n", sizeof(a), sizeof(b));

    b.A::a = 42;
    printf("%d\n", b.A::a);

    return 0;
}
Josh Townzen
@Josh Townzen: ohh. shouldn't there be name conflicts? [two variables with the same name](http://codepad.org/P132YXxr)?
Amoeba
@Poiuyt: It's legal for both variables to be named `a` because they have different scopes. It's similar to having a global variable `a`, then defining a local variable `a` within a function. The local variable will hide the global one, though you could still access the global variable by using `::a`.
Josh Townzen