Zachery
Zachery

Reputation: 131

C ++ Child class cannot inherit private member from Father class?

I am using Win8 VC++2012.

The code above is to show that child class B under NO circumstances can access the A::a. Neither can I change the access attribute of A::a but A::b and A::c.

So A::c is not inherited from A to B. But the sizeof(A) and sizeof(B) are 12 and 24 respectively, which means that A::a DO occupy memory in B.

  1. How could B stores A::a in its memory while never could access it?
  2. The book C++ Primer says, we can RESTORE the access attribute of base class member but can NOT change the it. Here my code shows that I can change access attributes of A::b from protected to public in B. Why?

Here's the code:

#include <iostream>
using namespace std;

class A
{
private:
    int a;
protected:
    int b;
public:
    int c;

    A(int a, int b, int c): a(a), b(b), c(c)
    {
        cout << "A: ";
        cout << a << " ";
        cout << b << " ";
        cout << c << endl;
    }
};

class B: protected A
{
private:
    int d;
protected:
    int e;
    //using A::a; COMPILE ERROR
public:
    int f;
    //A::a;  COMPILE ERROR
    using A::c; //RESTORE A::c public access
    A::b; // change A::b from protected to public

    B(int d, int e, int f): A(d, e, f), d(d), e(e), f(f)
    {
        cout << "B\n";
        //cout << a << endl; COMPILE ERROR
        cout << b << " ";
        cout << c << " ";
        cout << d << " ";
        cout << e << " ";
        cout << f << endl;
    }
};
int main()
{
    A a(1,2,3);
    B b(4,5,6);

    cout << "sizeof(A)=" << sizeof(A) << endl; //OUTPUT 12
    cout << "sizeof(B)=" << sizeof(B) << endl; //OUTPUT 24
    return 0;
}

Upvotes: 1

Views: 4646

Answers (4)

Boumbles
Boumbles

Reputation: 2523

When you use inheritance you are creating an instance of the base class along with an instance of the derived class. All the members inside of the base class are constructed when you instantiate a derived class, even if they are not accessible to the derived class.

If you need the member to be private in the base class but you still would like to access it in the derived class. Create a protected accessor in the base class that will give you access to the private member.

 protected:    
 int &geta() { return a; }

Upvotes: 1

stardust
stardust

Reputation: 5988

So A::c is not inherited from A to B

did you mean

So A::a is not inherited from A to B

But even then it is indeed inherited. It is just not directly accessible. However B will still have an a.

Why is this necessary? Because you can have public methods in A that can set or get the value of a. These functions can give B access to its own a indirectly.

For example

class A {
private:
    int a;      // a is private
public:
    void set_a(int i) {a = i;}
};

class B : protected A {
public:
    using A::set_a;   // we bring set_a to public access
};

int main() {
    B b;
    b.set_a(2);   // change b.a indirectly
    b.a = 2;      // Error
}

Upvotes: 1

Julien Greard
Julien Greard

Reputation: 989

I don't see what the problem is:

B is an A, that's why there is some space occuped by the a attribute even if B can't access it.

If there was a public method geta() returning a, how could it return a if a wasn't in B ?

Upvotes: 0

masoud
masoud

Reputation: 56479

Children inherit parent's private members, but they can not access them. To access make them protected

class A
{
protected: // <<------------ make `a` as protected in parent
    int a;

Upvotes: 7

Related Questions