Accessing parent's protected variables
Member functions of a particular class only have access to protected members of base classes that actually are base class subobjects of objects of their own class type (or more derived types).
Members of one class do not have access to protected members of other instances of that base class and so are also forbidden from accessing protected members through a reference or pointer to the base class type even if at runtime that pointer or reference might be to an object that is of the type of the class whose member function is attempting the access. Access control is enforced at compile time.
E.g.
class X
{
protected:
int z;
};
class Y : X
{
public:
int f( const Y& y )
{
return y.z; // OK
}
int g( const X& x )
{
return x.z; // Error, Y::g has no access to X::z
}
};
In your example, in the expression target->hp
, the access to target
is legal because you are accessing a member of the current object (which has the type of the class of which the function is a member, Child
), but the access to the member hp
is not legal because the type of target
is not a pointer to Child
, but a pointer to Parent
.
Protected variables can be accessed within Child Class or Child Object
Disclaimer: the answer is copied from my answer of another question. However no answer from that question is accepted. I believe it also suit this question therefore I am copying the content with some minor editing to here.
protected
is a bit interesting in Java. Although we always says "protected" give access to subclass of different package, it is not the whole picture.
For example, if you have Child
extending Parent
, and there is a protected member in Parent
. What you can do in Child
is to access that protected member of Child
, but not even that protected member of Parent
. Sounds a bit strange right although they sounds the same thing?
Quoted from Core Java 9th Edition:
However, the Manager class methods can peek inside the hireDay field
of Manager objects only, not of other Employee objects. This
restriction is made so that you can’t abuse the protected mechanism by
forming subclasses just to gain access to the protected fields
(class Manager extends Employee, and there is a hireDay protected member in Employee, and Manager and Employee are located in DIFFERENT package)
For example,
public class Manager extends Employee {
// accessing protected member of itself
public void foo1() {
System.out.println("" + this.hireDay); // OK
}
// access protected member of instance of same type
public void foo2(Manager manager) {
System.out.println("" + manager.hireDay); // OK
}
// access protected member of instance of super-class
public void foo3(Employee employee) {
System.out.println("" + employee.hireDay); // NOT ALLOWED!
}
}
Which means, protected member allow child class from another package to access through reference of that child class (either this
, or another reference that is-a child class)
And, be specific to OP's answer: if callMethod
is declared in ChildClass
, then NO, you cannot do it and it will not even compile. However if callMethod
is declared in ParentClass
then everything is fine, because it is simply ParentClass
accessing protected member of a ParentClass
instance.
Update:
Given criticisms in comment, I think it worth to go to JLS to see what it say:
(Quoted from http://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.2.1 about Access to a protected Member, second bullet)
If the access is by a field access expression E.Id, or a method
invocation expression E.Id(...), or a method reference expression E ::
Id, where E is a Primary expression (§15.8), then the access is
permitted if and only if the type of E is S or a subclass of S
This is essentially what I was trying to deliver in the answer:
Within Manager
class, manager.hireDay
works because manager
is a primary expression, and the access is permitted because type of manager
is Manager
or subclass of Manager
.
So, based on JLS, why manager.hireDay
works DOES have relationship with type of manager
(being the same type).
Accessing protected members in a derived class
A class can only access protected members of instances of this class or a derived class. It cannot access protected members of instances of a parent class or cousin class.
In your case, the Derived
class can only access the b
protected member of Derived
instances, not that of Base
instances.
Changing the constructor to take a Derived
instance will solve the problem.
Accessing protected variables from parent class in JRuby
Since this fix, package access, private
and protected
can be exposed by using field_accessor
or field_reader
:
require 'java'
java_import 'Something'
class Something
field_accessor :somethingelse
end
class Stuff < Something
def anotherstuff
puts self.somethingelse
end
end
Stuff.new.anotherstuff
Prevent Child class from accessing protected member variable of Grandparent class
MatG's comment about searching "c++ inheritance change member access specifier" answered by question. I didn't realize you could change the access modifier of a parent class member in a derived class.
class Parent : Grandparent
{
protected:
void setObj(val) { m_obj = val; }
MyClass getObj { return val; }
private:
using Grandparent::m_obj;
}
Access protected members of base class in grandchild class
Your problem is that you're inheriting from you base classes privately, so public and protected members of the base class get the same access control as private members of the derived class. While possible, private inheritance is a very specific tool and used rarely. In the vast majority of cases, you want public inheritance:
class SmallBox: public Box {
protected:
double height;
};
class TooSmall: public SmallBox {
public:
void setSmallWidth( double wid );
void setHeight(double hei);
double getSmallWidth( void );
double getHeight(void);
};
Done this way, protected members will be visible to all descendants (not just direct children) normally.
If, for some reason, you want to stick with private inheritance, you will have to "promote" the privately-inherited protected members back to protected:
class SmallBox:Box {
protected:
double height;
using Box::width; // make it protected again
};
class TooSmall:SmallBox {
public:
void setSmallWidth( double wid );
void setHeight(double hei);
double getSmallWidth( void );
double getHeight(void);
};
Related Topics
What's the Semantically Accurate Position for the Ampersand in C++ References
How to Set Error_Code to Asio::Yield_Context
Vector of Class Without Default Constructor
How Does the Friend Keyword (Class/Function) Break Encapsulation in C++
What Does Afx_Manage_State(Afxgetstaticmodulestate()) Do Exactly
How to Determine the Value of Socket Listen() Backlog Parameter
Reading Files Larger Than 4Gb Using C++ Stl
Fatal Error C1083: Cannot Open Include File: 'Xyz.H': No Such File or Directory
What Does the "::" Mean in "::Tolower"
Handling Ssl_Shutdown Correctly
Std::Optional - Construct Empty with {} or Std::Nullopt
Simple For() Loop Benchmark Takes the Same Time with Any Loop Bound
Why Can't a Function Go After Main
Double Dispatch/Multimethods in C++
How to Differentiate (When Overloading) Between Prefix and Postfix Forms of Operator++? (C++)
How to Write an Agile Pimpl in C++
Why Do I See 400X Outlier Timings When Calling Clock_Gettime Repeatedly