2

When I declare a member protected in base class and inherit as private in derived class , access to the member is not allowed

class base{
protected:
int a;
};
class derived : public base
{
protected:
int b;
public:
derived():base(){ a=0; b=0;}
void show(){cout<<"a= "<<a<<"\tb= "<<b;}
};
int main ()
{
derived d;
d.a=10;    //error: 'int base::a' is protected within this context
d.show();
}

But when I write the derived class, to grant public access for 'a' (protected in base)

class derived : public base 
{
protected:
int b;
public:
base::a;
};

int main ()
{
derived d; 
d.a=20;   // no error 
}

Now I can change value of 'a' in main() without any error.

I read in c++ complete reference book, granting access will restore access rights ,but one can not raise or lower the access status.

Can anyone tell me why I'm able to access protected member of base class ,inherited privately , and later given public access like a public variable of derived class ( doesn't it violate encapsulation ,ie Protected member should be restored as protected). Please guide me if my understanding is incorrect

saumitra mallick
  • 395
  • 2
  • 11
  • Protected variables only accessible in inside derived class. Protected variable is not a public one, that can be used as `d.a=20;`. – Ugnius Malūkas Nov 23 '17 at 20:54
  • protected gives the member to its derived class but it does not give to the public (outside usage) , when you public the protected member it's then publicly available to others too. – nullqube Nov 23 '17 at 20:59

2 Answers2

1

protected doesn't live up to its name. It just doesn't protect much; it's not very far from public.

The moment base says that a is protected, the field's fate is sealed - it's now practically open to the rest of the world. All you have to do is create a derived class, access the member variable and expose is to the outside world - which is what you did with derived when you wrote base::a (by the way, you normally add using before that).

You could even do that with a normal function, after all:

class base {
protected:
    int a;
};

class derived : public base 
{
protected:
    int b;
public:
    int& GotYou()
    {
        return a;
    }
};


int main ()
{
    derived d; 
    d.GotYou() = 20; // no error 
}

If you want protection, use private.

By the way, the following line probably gives you a wrong impression of how C++ works:

derived():base(){ a=0; b=0;}

What happens here is that base is constructed, a is default-initialised to an indeterminate value, then b is default-initialised to an indeterminate value and then two assignments are made. I recommend some research on initialisation lists.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
  • Thankyou for the feedback , with private it works fine (I get error when I try to change the access ).Initialization lists noted :) – saumitra mallick Nov 23 '17 at 22:27