How and why can I change the level of access to a member?

I ended up coding (with some help) in the end:

#include <iostream> using namespace std; class A { public: virtual void foo(){cout << "A::foo\n";} }; class B : private A { private: virtual void foo(){ cout << "B::foo\n";} void DoSomething(SomeOtherClass& o){o.DoSomething(*static_cast<A*>(this));} }; 

I tried changing the inheritance method:

 class B : public A { private: virtual void foo(){ cout << "B::foo\n";} }; int main() { A* a = new B; a->foo(); } 

It still works. I was expecting a compile-time error. Please tell me why this is possible and what are the possible use cases? I know one use because of the first scenario. You can expose different interfaces for different classes.

EDIT:

In the second case, the output is B::foo .

+6
c ++ design oop
source share
2 answers

I can not answer all your questions directly, however, I decided to put it here for future use. Also, please take it with a pinch of salt, as this is based on my understanding of the events that occurred in the world of C ++ standards, not actual data.

Read this . I do not have ARM with me, but the article provides the necessary details.

Note 115 in C ++ 0x says

115) The declaration of access is condemned; ad-member declarations (7.3.3) provide a better means of doing the same. In earlier versions of C ++, access declarations were more limited; They were generalized and made equivalent to use-declarations as a percentage of simplicity. Programmers are encouraged to use use-of-declarations rather than the new capabilities of declaring access in new code.

In short:

I think ARM first banned it:

An access declaration cannot be used to restrict access to a member that is available in the base class, nor will it be used to provide access to a member that is not available in the base class.

But later, I think when the Standard evolved it was eventually allowed

+1
source share
 using namespace std; class A { public: virtual void foo(){cout << "A::foo\n";} }; class B : public A { private: virtual void foo(){ cout << "B::foo\n";} }; int main() { A* a = new B; a->foo(); } 

This works because at compile time the compiler can only see that a is a pointer to the base class a and foo() is a public method that is called on a , which is absolutely true. Virtual binding occurs dynamically at runtime after compilation, this virtaul binding decides that the actual call is B::foo() , not A::foo() , which is a performance hit when using virtualism.

+3
source share

All Articles