class Base{
public:
void setX(int a) {x=a;}
private:
int x;
};
class D1: protected Base{};?
class D2: public D1{};
what is the access level for the member function setX() in the class D2 ?
is it protected ? of private?
Can any kind people explain this, I mean how to judge access level regarding inherence ....something like this. thank you!
Edited: Add on more question
but WHy I cannot call : d2.setX() ? d2 is a instance of D2. It turns out compiler error – user658213 0 secs ago edit
SetX is protected and x is inaccessible from D2. You can only restrict access, you cannot broaden it.
setX becomes protected via protected inheritance in D1, and remains protected through public inheritance in D2. Thus, its final access level in D2 is protected.
The reason you would not be able to call setX would depend on the calling context. If you are calling from outside of a class derived from Base or D1 (e.g. D2), then you wouldn't be able to call it for the same reason you can not call any protected members - they are only for use by derived classes.
Related
If B inherits from A using public, can B override one of the functions and force it to be private?
class A
{
public:
virtual double my_func1(int i);
virtual double my_func2(int i);
}
class B : public A // Notice the public inheritance
{
public:
virtual double my_func1(int i);
private:
virtual double my_func2(int i);
}
How about the other way around? if the inheritance type is private - can B force a specific function to be public?
What if A is pure abstract? does it make a difference?
Would protected make any difference in any combination?
If B inherits from A using public, can B override one of the functions and force it to be private?
NO
Eventhough the my_func1() is declared under priavte access specifier it can be still called through a pointer to class A, actually pointing to a object of class B
The call to my_func1() is evaluated at run time depending on the type of objected pointed by the pointer. At compile time the compile sees the my_func1() call as call to A::my_func1() and since A::my_func1() is public the compiler doesn't report only error. It is only at runtime that actual function call B::my_func1() is evaluated.
Ofcourse, You cannot directly call my_func1() through object of class B though because B::my_func1() is declared under Private Access specifier and You cannot access privately declared members from outside the class.
How about the other way around? if the inheritance type is private - can B force a specific function to be public?
NO
If you are calling my_func1() through a pointer of the Base class A, At compile time it is just evaluated as call to A::my_func1() which is Invalid since A::my_func1() is declared private inclass A`
What if A is pure abstract? does it make a difference?
NO
It makes no difference if the base class is Abstract or just polymorphic. Same rules will be applicable.
Would protected make any difference in any combination?
NO
As explained in first 2 Q's if you are calling a virtual function thorough pointer to Base class then at compile time the compiler only checks the access of that member function in Base class because compiler sees it as call to Base class member function. The actual call to the function is evaluated at run time and the feature is called Runtime Polymorphism or Dynamic polymorphism which is independent of the Access specifiers, which as a compile time construct.
So in conclusion,
overriding members of Base Class does not affect access
Difference
What if A is pure abstract? does it make a difference?
The only difference it makes is the following, i.e how they can (or cannot) be used:
A *pa = new B();
pa->my_func2(10); //calls B::my_func2() even though its private!
B *pb = new B();
pb->my_func2(10); //compilation error - trying to access private function
Explanation
Access-specifiers are compile-time construct, and so, the compiler detects any violation of access-rules at compile-time (obviously) based on the static type of the object (or pointer). Such violation cannot be detected at runtime.
So pa->my_func2() works, because the compiler sees that the static type of pa is A* which has a public function my_func2() defined, so the expression pa->my_func2() passes the compiler's test. Hence it works.
But pb->my_func2() doesn't work, since the static type of pb is B* which has a private function my_func2(), hence the code wouldn't even compile!
==> If B inherits from A using public, can B override one of the functions and force it to be private?
NO. Pointer/reference to A will always see my_func2 as public. You can still call this method using A* or A&. (what you ask is possible in Java).
==> if the inheritance type is private - can B force a specific function to be public?
At 1st place if the inheritance type is private/protected then you can NOT assign object of Derived class to Base class pointer/reference. e.g. you can not do following!!
A* p = new B; // error
==> What if A is pure abstract? does it make a difference?
NO difference (except you have to define methods in B)
==> Would protected make any difference in any combination?
NO difference (with respect to Base class)
I was going through posts made by others and found explanation related to errors encountered when inheritance being private/protected in Derived class somewhat confusing/incomplete.
Consider below code snippet,
class A
{
public:
virtual double my_func1(int i);
virtual double my_func2(int i);
}
class B : private A // Notice private inheritance
{
public:
virtual double my_func1(int i);
private:
virtual double my_func2(int i);
}
A* ptr = new B; // this is not legal because B has a private base
ptr->my_func1(); // my_func1() is not accessible
ptr->my_func2(); // my_func2() is also not accessible not because it is private but due
// base class A being inherited privately
So when we inherit class B from class A using private/protected specifiers then it means that nobody in outside world knows that class B has inherited from class A hence it's illegal to assign pointer/reference of type class B to pointer/reference of type class A. Hence, access of private/protected overridden virtual function in derived classes is only valid when inheritance in public.
What you override does not affect access. So you can create public override of privately inherited function exactly the same way you create private override of publicly inherited function.
The public override of the privately inherited function obviously has to call the real function and it should be inline, so the compiler will optimize it away.
If B inherits from A using public, can B override one of the functions and force it to be private?
class A
{
public:
virtual double my_func1(int i);
virtual double my_func2(int i);
}
class B : public A // Notice the public inheritance
{
public:
virtual double my_func1(int i);
private:
virtual double my_func2(int i);
}
How about the other way around? if the inheritance type is private - can B force a specific function to be public?
What if A is pure abstract? does it make a difference?
Would protected make any difference in any combination?
If B inherits from A using public, can B override one of the functions and force it to be private?
NO
Eventhough the my_func1() is declared under priavte access specifier it can be still called through a pointer to class A, actually pointing to a object of class B
The call to my_func1() is evaluated at run time depending on the type of objected pointed by the pointer. At compile time the compile sees the my_func1() call as call to A::my_func1() and since A::my_func1() is public the compiler doesn't report only error. It is only at runtime that actual function call B::my_func1() is evaluated.
Ofcourse, You cannot directly call my_func1() through object of class B though because B::my_func1() is declared under Private Access specifier and You cannot access privately declared members from outside the class.
How about the other way around? if the inheritance type is private - can B force a specific function to be public?
NO
If you are calling my_func1() through a pointer of the Base class A, At compile time it is just evaluated as call to A::my_func1() which is Invalid since A::my_func1() is declared private inclass A`
What if A is pure abstract? does it make a difference?
NO
It makes no difference if the base class is Abstract or just polymorphic. Same rules will be applicable.
Would protected make any difference in any combination?
NO
As explained in first 2 Q's if you are calling a virtual function thorough pointer to Base class then at compile time the compiler only checks the access of that member function in Base class because compiler sees it as call to Base class member function. The actual call to the function is evaluated at run time and the feature is called Runtime Polymorphism or Dynamic polymorphism which is independent of the Access specifiers, which as a compile time construct.
So in conclusion,
overriding members of Base Class does not affect access
Difference
What if A is pure abstract? does it make a difference?
The only difference it makes is the following, i.e how they can (or cannot) be used:
A *pa = new B();
pa->my_func2(10); //calls B::my_func2() even though its private!
B *pb = new B();
pb->my_func2(10); //compilation error - trying to access private function
Explanation
Access-specifiers are compile-time construct, and so, the compiler detects any violation of access-rules at compile-time (obviously) based on the static type of the object (or pointer). Such violation cannot be detected at runtime.
So pa->my_func2() works, because the compiler sees that the static type of pa is A* which has a public function my_func2() defined, so the expression pa->my_func2() passes the compiler's test. Hence it works.
But pb->my_func2() doesn't work, since the static type of pb is B* which has a private function my_func2(), hence the code wouldn't even compile!
==> If B inherits from A using public, can B override one of the functions and force it to be private?
NO. Pointer/reference to A will always see my_func2 as public. You can still call this method using A* or A&. (what you ask is possible in Java).
==> if the inheritance type is private - can B force a specific function to be public?
At 1st place if the inheritance type is private/protected then you can NOT assign object of Derived class to Base class pointer/reference. e.g. you can not do following!!
A* p = new B; // error
==> What if A is pure abstract? does it make a difference?
NO difference (except you have to define methods in B)
==> Would protected make any difference in any combination?
NO difference (with respect to Base class)
I was going through posts made by others and found explanation related to errors encountered when inheritance being private/protected in Derived class somewhat confusing/incomplete.
Consider below code snippet,
class A
{
public:
virtual double my_func1(int i);
virtual double my_func2(int i);
}
class B : private A // Notice private inheritance
{
public:
virtual double my_func1(int i);
private:
virtual double my_func2(int i);
}
A* ptr = new B; // this is not legal because B has a private base
ptr->my_func1(); // my_func1() is not accessible
ptr->my_func2(); // my_func2() is also not accessible not because it is private but due
// base class A being inherited privately
So when we inherit class B from class A using private/protected specifiers then it means that nobody in outside world knows that class B has inherited from class A hence it's illegal to assign pointer/reference of type class B to pointer/reference of type class A. Hence, access of private/protected overridden virtual function in derived classes is only valid when inheritance in public.
What you override does not affect access. So you can create public override of privately inherited function exactly the same way you create private override of publicly inherited function.
The public override of the privately inherited function obviously has to call the real function and it should be inline, so the compiler will optimize it away.
Let's say we have two classes, Base and Derived. There are two methods, getX and setX, which are public and use a protected int x to interface with the user. Base construction sets x to 1, and Derived construction sets x to 3.
class Base {
public:
Base();
int getX();
void setX(int n);
protected:
int x;
}
int Base::getX() {
return x;
}
void Base::setX(int n) {
x = n;
}
Base::Base() : x(1) {
}
class Derived : public Base {
public:
Derived();
}
Derived::Derived() : x(3) {
}
The Derived class has full access to the methods from Base. Great.
Let's say that for some reason I don't want setX to be available to users of the Derived class. There are a couple ways I thought of doing it.
1) Redeclare setX as private in Derived, so shadowing prevents the user from accessing that method entirely.
2) Redeclare x as a private const int in Derived. However, this results in setX and getX working with Base::x.
3) Make Base::setX a virtual function, make a Derived::setX function that does nothing.
What's the best way to handle this?
As Derived publicly derived from Base, what you are trying to do does not make much sense. You should instead use private or protected inheritance and then provide access in Derived only to methods from Base that you need, not the way around.
First, as observed by anatolyg, shadowing setX method in 1) by making it private in Derived class does not prevent someone to call it on the Base class directly by casting.
So 1) is only ok if you accept this.
Otherwise, if you only want to provide an implementation of setX in Base class to many derived class, but without making it public either to Base or derived class user. just make setX method protected in Base class. In this case you could probably also make x private, and call setX method from Derived constructor.
If you only want to forbid user of any instance of Derived class to call the setX method on that object... but still have it in the interface, well obviously you could as you proposed in 3) make it a virtual function in Base and implement it empty in Derived.
But in this case you are going against the inheritance motto of "is a" (obviously your derived class doesn't behave like the Base class).
If what you are looking is a compilation error to forbid this call,
may be you could rethink your hierarchy:
class real_Base; which does not implements setX method
class Base : public real_Base; which implements setX method
class Derived : public real_Base; which does not implement setX method
In this case then:
you would use real_Base as interface when your client code does not need to call setX.
use Base when call to setX is allowed
use Derived when call to setX is forbidden.
You aren't overriding any virtual functions so inheritance is dubious.
Do you want users to use the Base interface or the Derived interface? If you say Derived, again that's dubious.
Compose Derived from Base and give it a better name:
class Composite {
private:
Base base;
public:
Composite() : base(3) {
}
};
You cannot initialize member x in the initializer list of Derived, since x is not a member of Derived. Your compiler should issue an error.
I have seen this question http://www.careercup.com/question?id=384062
class Base {
public :
virtual void method () = 0;
private :
int n;
};
void Base::method() { n = 1;}
class D1 : Base {};
class D2 : public D1 {
int i;
void method() {i = 2;}
};
It passed the compiler of vs2008 and g++ 4.4.3
Here is my understanding of above code, please correct me if I am wrong
S1> D1 has inherited variable Base::n but it cannot access it.
S2> D1 has inherited the function Base::method but it doesn't call/modify this inherited function in the above implementation.
S3> D2::method is not an overridden version of D1::method
S2 and S3 are wrong.
D1's methods can call it's Base::method(), but other code can't as Base part of D1 is private.
Base::method() is overridden by D2. If you somehow convert (new D2) to (Base*) and call Base::method, the i=2 code will run.
Considering access control, if you have pointer to Base*, external code can use ->method() because it's public, and if you have pointer to D2*, ->method() can't be called because it's private, even if it's the same object and the same method.
Also, despite your (n=1) implementation for Base::method() it and its class remain abstract.
D1 has inherited variable Base::n but it cannot access it.
Correct.
Private members of a class are never accessible from anywhere except the members of the same class.
D1 has inherited the function Base::method but it doesn't call/modify this inherited function in the above implementation.
Correct, but conditonally, Read below for why:
D1 inherits the Base::method but it is not calling/invoking it because you did'nt add any statement to do so. But it can call it.
Pure virtual functions can have a body and they can be called by drived class members just like any other member function.
class D1 : Base
{
public:
void doSomething()
{
Base::method();
}
};
Note that in your Base class n is private so the only way to access it is through member function of Base & since only method() can do so, You can do it through it.
Note that presence of atleast one pure virtual function makes an class Abstract Class, And one cannot create objects of an Abstract class. Any class deriving from an Abstract class must override ALL the pure virtual functions of the Base class or else the derived class becomes an Abstract class as well.
Based on above rule,
In your case both Base and D1 are Abstract classes.
D2::method is not an overridden version of D1::method
Incorrect
Though method() is not acessible to the ouside world through instance of class D1, it is still very much a part of it. Access control dictates access rights not presence or absence of members.
So, Yes, D2::method is an overriden version of D1::method and it hides it as well, just that in this case, D1::method was not acccessible in the first place
In this case both Base and D1 classes are abstract classes which cannot be instantiated.
S1 - yes
S2 - Yes D1 has inherited the function. Can you please clarify your question.
S3 - No. D2::method is the override you have provided for the D2 class.
Edit:
I just noticed the private inheritance of D1 from Base class. In that case, S1 and S2 still hold good.
Updated: S3: D2::method is both overriding and hiding the base class method.
S1: Correct
S2: Correct
S3: Correct, more clearly D2::method hides D1::method
S1 - Correct
S2 - Sorry I'm not very clear what you meant. In D1 or subclasses you can define method() to override it in Base but cannot call it. And, D1* cannot be converted to Base* because of private inheritance.
S3 - Incorrect. Once you declare a member function as virtual in the base class, it will keep virtual in subclasses even you leave out virtual. So in your case, method() in D2 is a overridden version of D1::method() and Base::method().
Assume you have a class that defines virtual methods with the access specifier public.
Can you change the access specifier on your overriden methods?
I am assuming no.
Looking for an explanation.
The answer is: sort of. You can only change the access of members the derived class has access to. The type of inheritance has no effect - this only controls the default access for inherited members (to a point, following other rules).
So, you can make a base class's protected members public or private; or a base's public members protected or private. You cannot, however, make a base's private members public or protected.
Example:
class Foo
{
protected:
void protected_member();
private:
void private_member();
public:
void public_member();
};
class Bar : private Foo
{
public:
using Foo::protected_member;
using Foo::private_member;
using Foo::public_member;
};
int main(int, const char**)
{
Bar bar;
return 0;
}
The above code elicits the following error on g++ 4.1.2:
main.C:7: error: 'void Foo::private_member()' is private
main.C:14: error: within this context
Additionally, overriding has nothing to do with changing the access of a method. You can override a virtual private method, you just cannot call it from a derived class.
Yes you can, but it "doesn't grok".
Take a look at Overriding public virtual functions with private functions in C++
You definitely can. But it makes no sense. If it is a public inheritance, then you can always cast an object to its base. If it's a private inheritance, all base methods are already private by default. In case of protected inheritance you can make the base method private, so you prevent possible derived classes from calling it, but I don't really understand why one might need it.
Yes you can, and in fact you don't even need to override or use virtual anything.
class ABC {
public: // or this may be protected, no difference
void woof();
void moo();
};
class D : private ABC { // now woof and moo are private
public:
using ABC::woof; // using declaration to make woof public again
ABC::moo; // access declaration (deprecated) does the same
};
The same works if they are virtual, too. Or, as others noted, virtual function lookup ignores the access specified by the implementing class; any class you can cast to may provide access at compile time.
On the other hand, without the special declarations in D, the public interface of ABC would indeed be inaccessible through D because you wouldn't be able to upcast to ABC. And if woof and moo were virtual, you would want to make the overrides private to hide them. Perhaps that better answers the question.