Why in this code you cannot use the function of the protected member of the class?

#include <iostream> class Base { protected: void somethingProtected() { std::cout << "lala" << std::endl; } }; class Derived : public Base { public: void somethingDerived() { Base b; b.somethingProtected(); // This does not compile somethingProtected(); // But this is fine } }; int main() { Derived d; d.somethingDerived(); return 0; } 

I thought that perhaps only the protected members of this can be used, and the protected members of other instances are forever inaccessible.

But:

 class Derived : public Base { public: void somethingDerived(Derived& d) { d.somethingProtected(); // This compiles even though d is // potentially a different instance } void somethingDerived(Base& b) { b.somethingProtected(); // This does not } }; 

I feel disgusted by this since I programmed in C ++ for a while, but I could not find an explanation for this behavior.

EDIT:

It does not matter if it is the same or a different instance:

 int main() { Derived d1, d2; // Two different instances d1.somethingDerived(d2); // This compiles fine d1.somethingDerived(d1); // This compiles fine return 0; } 

EDIT2:

It seems that when it comes to access rights, it doesn’t matter at all that the instance is used for the class:

 class Base { public: void something(Base& b) // Another instance { ++ba; // But can enter private members } private: int a; }; 
+50
c ++ oop
May 28 '13 at 6:17
source share
4 answers

Despite the fact that access control in C ++ works on the basis of each class (as opposed to the basis for each instance), the protected access specifier has some features.

The language specification wants to make sure that you are accessing the protected member of some base subobject belonging to a derived class. You should not have access to the protected members of some unrelated, independent base type objects. In particular, you cannot access protected members of autonomous objects of a basic type. Access to protected members of base objects that are embedded in derived objects as base subobjects is permitted only.

For this reason, you need to access protected members through the syntax pointer->member , reference.member or object.member , where the pointer / link / object refers to the derived class.

This means that in your example, the protected member somethingProtected() not available through Base objects, Base * or Base & pointers, but is available through Derived objects, Derived * and Derived & pointers Derived & references. Your simple access somethingProtected() allowed, as it is simply a shorthand for this->somethingProtected() , where this is of type Derived * .

b.somethingProtected() violates the above requirements.

Note that in accordance with the above rules in

 void Derived::somethingDerived() { Base *b = this; b->somethingProtected(); // ERROR this->somethingProtected(); // OK } 

the first call will also fail, and the second will be compiled, although both are trying to access the same object.

+62
May 28 '13 at 6:28
source share

I believe that you have confusion about how to access the elements of the base class. The only way:

 class Derived : public Base void drivedMethod() { Base::baseMethod(); } 

in your example, you are trying to access a protected member of another instance.

The derived instance will have access to its own protected members, but not to other protected instance of the class, this is by design.

In fact, access to the protected members of another class, from other members of the instance, or from the main function is actually available as open access ...

http://www.cplusplus.com/doc/tutorial/inheritance/ (find the access specifier table to see the different levels)

Both examples prove the same thing:

 void somethingDerived(Base& b) { b.somethingProtected(); // This does not 

here your Derived class gets b as a parameter, so it gets another instance of the database, and then because b.somethingProtected is not public, it will not match.

this will match:

 void somethingDerived() { Base::somethingDerived(); 

your second example is fine because you are accessing a public method in another class d

 > void somethingDerived(Base& b) > { > b.somethingProtected(); // This does not > } 
+3
May 28 '13 at 6:19 06:19
source share

The Derived class can only access the protected base member in Derived objects. It cannot access a member in objects that are not (necessarily) Derived objects. In the event of a failure, you are trying to access the element through Base & , and since this may refer to an object that is not Derived , access cannot be made.

+1
May 28 '13 at 6:28
source share

What you did is illegal in C ++. The protected member cannot be accessed by the class object. Only members can access protected members. protected members behave exactly like private members, except that they are inherited by a derived class. Consider the program below to understand the difference between private, public, and protected members.

 class Base { private: void somethingPrivate() { std::cout << "sasa" << std::endl; } public: void somethingPublic() { std::cout << "haha" << std::endl; } protected: void somethingProtected() { std::cout << "lala" << std::endl; } }; class Derived : public Base { public: void somethingDerived() { Base b; b.somethingPublic(); // Works fine. somethingProtected(); // This is also fine because accessed by member function. //b.somethingProtected(); // Error. Called using object b. //somethingPrivate(); // Error. The function is not inherited by Derived. } }; 
+1
May 28 '13 at 6:33
source share



All Articles