How to access a protected method in a base class from a derived class?

Here is an example of code that annoys me:

class Base { protected: virtual void foo() = 0; }; class Derived : public Base { private: Base *b; /* Initialized by constructor, not shown here Intended to store a pointer on an instance of any derived class of Base */ protected: virtual void foo() { /* Some implementation */ }; virtual void foo2() { this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */ } }; 

How do you access a protected overridden function?

Thanks for your help .: O)

+8
c ++ protected derived-class
source share
6 answers

Protected members in the base class are accessible only to the current object.
Thus, you are allowed to call this->foo() , but you cannot call this->b->foo() . It doesn’t depend on whether the Derived implementation exists for foo or not.

The reason for this limitation is that otherwise it would be very easy to bypass secure access. You simply create a class like Derived , and suddenly you also have access to parts of other classes (for example, OtherDerived ) that should have been inaccessible to outsiders.

+8
source share

You usually do this with Base::foo() , which refers to the base class of the current instance.

However, if your code should do it the way you are trying to, and this is not allowed, you need to either make foo () public or make Derived a friend of the base.

+5
source share

One solution would be to declare a static protected function in Base that redirects the call to the private / protected function ( foo in the example).

Let's say:

 class Base { protected: static void call_foo(Base* base) { base->foo(); } private: virtual void foo() = 0; }; class Derived : public Base { private: Base* b; protected: virtual void foo(){/* Some implementation */}; virtual void foo2() { // b->foo(); // doesn't work call_foo(b); // works } }; 

Thus, we do not break encapsulation, because the Base constructor can make an explicit choice to allow all derived classes to call foo on top of each other, while avoiding putting foo in the public interface or explicitly turning all possible Base subclasses into friends.

Furthermore, this method works whether foo virtual or not, or whether it is confidential or secure.

Here is a link to the current version of the code above and here is another version of the same idea with a bit more business logic.

+2
source share

It's a bit fragile, but with the classes you defined here, won't this work?

 virtual void foo2() { reinterpret_cast<Derived *>(this->b)->foo(); } 

Reinterpret_cast points to a VTABLE for the base object and calls it through this access element.

+1
source share

You call the base functions explicitly using the scope operator (Base :: foo ()). But in this case, the Base class does not define foo (it's pure virtual), so there really is no function to execute when you say this->b->foo(); since b is a pointer to Base and not Derived.

0
source share

How do you access a protected overridden function?

--- where from?

You can access the protected member only through inheritance (except for methods of the same class). Say, for example, you have a class Derived1 that inherits from Derived , then Derived1 objects can call foo() .

EDIT: MSDN article on secure access specifier.

0
source share

Source: https://habr.com/ru/post/650986/


All Articles