Access to protected member through member-pointer: is it a hack?
The fact that a member is not accessible using class member access expr.ref (aclass.amember
) due to access control [class.access] does not make this member inaccessible using other expressions.
The expression &Derived::value
(whose type is int Base::*
) is perfectly standard compliant, and it designates the member value
of Base
. Then the expression a_base.*p
where p
is a pointer to a member of Base
and a_base
an instance of Base
is also standard compliant.
So any standard compliant compiler shall make the expression other.*(&Derived::value);
defined behavior: access the member value
of other
.
Why is it impossible to get a pointer to a protected method of the base class?
If you were able to take a pointer to A::foo
, you could use it to invoke foo
on an object of type A
or of type C
derived from A
:
class B : public A {
public:
void xx(A a) { auto tmp = &A::foo; a.*tmp(); } // illegal
}
Instead, take a pointer to B::foo
; this is fine because you can only use it on objects of type B
, your own class.
Pointer to base class method with protected inheritance
Why is this not possible, when I have used using and I can call operator directly?
The using declaration gives you access to the name operator[]
. But it doesn't alter the member's type. It staysint &(Foo::*)(size_t)
. Note the Foo
.
So converting to the declared type of o
requires a conversion down the inheritance tree. This conversion must check that the target class is indeed derived from the base, but that is an inaccessible base.
One way to work around it is to give Bar
a member function that returns that pointer. Inside Bar
's scope the base will be accessible to the conversion. Also, this sort of conversion requires a static_cast
.
Taking a pointer to a protected method of the base class and passing it to a different class
Expanding on robal's perfectly correct answer, I've rewritten the constructor of my class so that I don't need a manual type cast:
template <class TargetInstanceClass, class TargetMethodClass>
CCallback(TargetInstanceClass * target, void (TargetMethodClass::*targetMethod)(Arguments...))
{
void (TargetInstanceClass::*targetInstanceMethod)(Arguments...) = static_cast<void (TargetInstanceClass::*targetInstanceMethod)(Arguments...)>(targetMethod);
}
protected members are not accessible through a pointer or object
You are trying to access the member of an other instance of your mother class:classProb
, but inheritance make you able to access protected member of your own parent class only.
One way to correcting (but it strongly depend of what you are trying to do) is to put an getter of _probClass
in your Training class and call it in your test, for instance for the _probCalc member:
public:
(Type) Training::getProbCalc() {
return _probCalc;
}
the to change your call in the loop:
for (it3 = classProb.getProbCalc().begin(); it3 != classProb.getProbCalc().end(); it3++)
If you are trying to acces your own member inherited by your mother instance just call them directly. For instance:
for (it3 = _probCalc().begin(); it3 != _probCalc().end(); it3++)
How to access protected method in base class from derived class?
Protected members in a base-class are only accessible by the current object.
Thus, you are allowed to call this->foo()
, but you are not allowed to call this->b->foo()
. This is independent of whether Derived
provides an implementation for foo
or not.
The reason behind this restriction is that it would otherwise be very easy to circumvent protected access. You just create a class like Derived
, and suddenly you also have access to parts of other classes (like OtherDerived
) that were supposed to be inaccessible to outsiders.
c++ protected pointer member to the same class and access privileges
The compiler will allow that an object A
accesses private/protected members of an object B
if A
and B
have the same static type.
I will try to make this clear with an example:
class Base
{
protected:
int a;
};
class Derived : public Base
{
public:
void foo(Base& b, Derived& d)
{
//allowed because this obviously has the same type as this :)
a = 1;
//allowed because this has the same type as d (Derived)
d.a = 1;
//not allowed because this (Derived) does not have the same
//type as b (Base). They might have the same dynamic type
//but the compiler has no way of knowing this.
b.a = 1;
}
};
So, to answer your questions:
- Class
node
is allowed to access thename
field if thenode
pointers of yourargs
vector because they are also of classnode
. - You cannot directly. You either have to make the field public (I wouldn't do that) or make public accessors.
Related Topics
Do You Know Tool Building Tree of Include Files in Project\File
How to Set Pointer to a Memory to Null Using Memset
What Is the Size of Sizeof(Vector)? C++
How to Use Wndproc as a Class Function
Undefined Reference to Template Members
Why It Is Different Between -2147483648 and (Int)-2147483648
How to Get the Current Windows System-Wide Timer Resolution
Memory Model Ordering and Visibility
Std::Cin Doesn't Throw an Exception on Bad Input
How to Get Hwnd of Window Opened by Shellexecuteex.. Hprocess
Eigen::Ref for Concatenating Matrices
How Does Intel Tbb's Scalable_Allocator Work
Error Redeclaring a for Loop Variable Within the Loop
Is Std::Array<T, S> Guaranteed to Be Pod If T Is Pod