class B{
private:
void DoSomething();
}
class W{
private:
class D: public B{
}
D d;
}
Can I call private member function in base class of D in the scope of class W?
Nope. You can never call a private member function from anywhere except the class that owns it. If you want derived classes to be able to access it, declare it protected instead.
You can also declare D to be a 'friend' of class B; that would allow D to access B.DoSomething(). However, this approach is usually frowned upon.
The function DoSomething can be accessed outside the class only if it is declared as public or private. Besides as mentioned above by Aric, the inherited class can become a friend to achieve the same.
The alternative approach would be to declare/define the function as virtual and do not define the virtual definition for the sub/inherited class. Doing this, will call the function definition for the base class.
No, if you use the protected keyword then you can. The fact that it is a nested class is irrelevant.
Related
I have an abstract class base with private member variable base_var. I want to create a derived class, which also has base_var as a private member.
To me, this seems like an obvious thing you would want to do. base is abstract so it will never be instantiated. The only time I will create a base-object is if it is actually a derived object, so obviously when I give ´base´ a private member variable, what I am really trying to do is give that variable to all of its derived objects.
However, the below diagram seems to suggest that this is not doable with inheritance?
Why not? What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
However, the below diagram seems to suggest that this is not doable with inheritance?
Correct, private members of a class can not be accessed by derived classes. If You want a member of a class to be accessible by its derived classes but not by the outside, then You have to make it protected.
Why not? What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
Even an abstract class can have member functions which act on a (private) member variable. Consider (somewhat silly example, but well):
class MaxCached
{
private:
int cache = std::numeric_limits<int>::min();
public:
bool put(int value)
{
if (value > cache)
{
cache = value;
return true;
}
return false;
}
int get() const
{
return cache;
}
virtual void someInterface() const = 0;
};
Deriving from this class gives You the functionality of the base class (put and get) without the danger of breaking it (by for example writing a wrong value to cache).
Side note: Above is a purely made up example! You shouldn't add such a cache (which is independent of Your interface) into the abstract base class. As it stands the example breaks with the "Single Responsibility Principle"!
Just because a class is abstract doesn't mean there cannot be code implemented in that class that might access that variable. When you declare an item in a class to be private, the compiler assumes you had a good reason and will not change the access just because it there is a pure virtual function in the class.
If you want your derived classes to have access to a base class member declare the member as protected.
I have an abstract class base with private member variable base_var
class foo {
public:
virtual void a_pure_virtual_method() = 0;
int get_var() { base_var; }
virtual ~foo(){}
private:
int base_var;
};
Note that a class is said to be abstract when it has at least one pure virtual (aka abstract) method. There is nothing that forbids an abstract class to have non-pure virtual or even non-virtual methods.
I want to create a derived class, which also has base_var as a private member.
class derived : public foo {};
To me, this seems like an obvious thing you would want to do.
Sure, no problem so far.
The only time I will create a base-object is if it is actually a derived object, so obviously when I give ´base´ a private member variable, what I am really trying to do is give that variable to all of its derived objects.
Still fine.
Why not?
You are confusing access rights that are display in the image you included with the mere presence of the members in the derived. The derived class has no access to members that are private in the base class. Period. This is just according to the definition of what is private.
What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
It is not useless at all. Derived classes inherit all members, they just cannot access all of them. The private stuff is there you just cannot access it directly. Thats the whole point of encapsulation. Consider this example:
class bar : public foo {
void test() {
std::cout << base_var; // error base_var is private in foo
std::cout << get_var(); // fine
}
};
I have a template base class.Lets say.
template<class KeyF>
class Base
{
private:
int member1;
char member2;
....
};
I derived another class from above class.
template<class KeyF>
class Derived : public Base<KeyF>
{
public:
void func1() {
<accessing member1/member2>
}
....
};
Above code doesn't compile in gcc. saying that member1 is not a member of Derived. But it is already derived from a Base Class, then why can't it access its member?
Members in Base are private. You cannot access private members of class, outside of this class (except friend). Make them protected, or make protected getters.
You need to prefix base member names with this-> or Base<KeyF>::, or add a using declaration to the class to unhide them. Their names are dependent names, and they are hidden.
Did you try protected? Been a bit since I was deep into C++...
I think two changes needed to solve the issue:
In base class, define the member as "protected" instead of "private" to be accessible in the derived class.
In derived class, add the base class name ahead of the protected member. In this case, it should look like "Base<typename>::member1".
Using C++17 standard in my case, the issue was resolved. Hope this is helpful. Thanks to Kerrek SB for the info.
Suppose I have a Base class and its derived class Derived as follows:
class Base{
private:
_privateVar;
protected:
protectedVar;
public:
publicVar;
void publicMethod(someValue, anotherValue)
{
protectedVar = someValue;
publicVar = anotherValue;
}
};
class Dervied: public Base{
protected:
protectedVar:
};
int main(void)
{
Dervied d;
d.publicMethod(valueA, valueB);
}
My question-
When I call d.publicMethod(...), does the protectedVar in Derived get set or the one in Base class?
Thanks
--A
It is of Base class. Base class cannot access derived class members.
When I call d.publicMethod(...), does the protectedVar in Derived get set or the one in Base class?
The method is a member of the Base class and hence it can access only the members of the Base class.
If the method belonged to your Derived class, then it would access Derived class member.
Because Derived class data members always hide Base class data members when accessed inside their own member functions.
You cannot override a member variable, you can create another different variable in a different level in the hierarchy that has the same name, but they will be two unrelated variables. Within the context of the use of the variable, lookup will find one or the other and that is the one that will be picked up and used.
Polymorphism only applies to virtual member functions, not to non-virtual functions, not to member variables either.
Since publicMethod is a methoc of the Base class, the protectedVar of the base class is set.
I don't know if this is what you want or expect, but even if this is what you want, I think it is not advised to do it like this. Tools like PC-LINT will probably also warn you about such a construction.
The member in the base class is modified. Data members never behave as if they are virtual.
When the compiler reaches the definition of Base::publicMethod, it has to statically resolve all the names it uses. At that point, the only possible resolution of those names are the members of Base, so the generated code will access those members.
Subclassing Base later on does not, and could not possibly, go back and change the code generated for Base::publicMethod. The derived class could be in a different translation unit, or in a dynamically-loaded library.
If you want dynamic lookup, access protectedVar via a protected virtual accessor function: that would allow a derived class to interpose its own storage for the variable.
If Base::protectedVar and Derived::protectedVar have the same type anyway, it's hard to see what you expect to gain, but it would look like:
class Base
{
Type protectedVarImpl;
protected:
virtual Type & protectedVar();
virtual Type const & protectedVar() const;
public:
void publicMethod(someValue, anotherValue)
{
protectedVar() = someValue; // Note the method call
publicVar = anotherValue;
}
};
Type& Base::protectedVar() { return protectedVarImpl; }
I have not used C++ for a really (really) long time and this question may be stupid but I could really use some help.
If my base class has a private data member and my derived class is derived publicly, the private members of the base class are NOT inherited. But, they can still be accessed via the inherited public functions. Eg:
class B{
int a,b;
public:
void SetA(int);
int GetA();
};
class D:public B{
public:
SetAAttribute(int x)
{ SetA(x); }
}
Now, my question is as follows:
Technically, the derived class objects do not have the 'a' attribute defined on them. In layman terms, I am basically setting an attribute on an entity when the attributes does not even exist in the first place. It seems unintuitive to imagine such a concept. Did I understand this correctly?
Any extra explanation or correction would be greatly appreciated.
It's not that the attribute doesn't exist anymore, it's just that it's hidden from you. The base class methods can still access the base class members because they're not hidden from each other.
The private base members are inherited, the compiler will just give you an error if you try to access them, since you aren't supposed to access them directly.
I have a class A, which have a field val declared as private.
I want to declare a class B, that inherit from A and have an access to val.
Is there a way to do it on C++?
I want to do it because I need to overload some functions of A, without changing A code at all.
Thanks.
Quick answer: You don't. Thats what the protected key-word is for, which you want to use if you want to grant access to subclasses but no-one else.
private means that no-one has access to those variables, not even subclasses.
If you cannot change code in A at all, maybe there is a public/protected access method for that variable. Otherwise these variables are not meant to be accessed from subclasses and only hacks can help (which I don't encourage!).
Private members of a base class can only be accessed by base member functions (not derived classes). So you have no rights not even a chance to do so :)
class Base
public: can be accessed by anybody
private: can only be accessed by only base member functions (not
derived classes)
protected: can be accessed by both base member functions and derived
classes
Well, if you have access to base class, you can declare class B as friend class. But as others explained it: because you can, it does not mean it's good idea. Use protected members, if you want derived classes to be able to access them.
It is doable as describe in this Guru of the Week - GotW #76 - Uses and Abuses of Access Rights. But it's should be considered a last resort.
You need to define it as protected. Protected members are inherited to child classes but are not accessible from the outside world.
You can access the private members of a base class say A through an inherited member function of A
#include<iostream>
using namespace std;
class A{
int a;
public:
A(){};
A(int val){a=val;};
int get_a(){//To access a private variable it must be initialized here
a=10;
return a;
}
};
class B: public A{
int b;
public:
B(){};
B(int val){b=val;};
void get(){
cout<<get_a();
}
};
int main(){
A ob1(2);
cout<<ob1.get_a()<<endl;
B ob2(4);
ob2.get();
return 0;
}