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.
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 created two classes A and B where B inherits from class A. As you can see, I have a vector in class A that is currently under the protected section of the class. I am unsure if using protected is bad practice?
#include <vector>
class A
{
public :
A();
protected:
std::vector <std::string> a;
};
class B : A
{
public :
B();
void accessVector()
{
a.size();
}
private:
};
When A makes a data member a protected, it is offering the following guarantee to all classes that derive from it:
"You may do anything you like to a without telling me. This includes appending to it, modifying its contents, removing items, sorting it, moving from it, moving to it and otherwise making its state undefined and/or unknowable to me".
Remember that anyone may create a class that derives from A.
For this reason, to all intents and purposes, a protected member is a public member, since a derived class may simply say the following:
public:
using A::a;
Starting here and working forward, you'll find that there are only two sensible use-cases for protected:
When a base class defines a virtual member function that may need to be called from an overridden version of the same function in a derived class.
When the base class wants to expose 'data as interface' to a derived class, but not to the world.
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.
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;
}
Sorry if the question is silly. I come from java background.
In the following code, base_list is a parent class of SqlAloc, but what's the meaning of public memory?
class base_list :public memory::SqlAlloc
{
protected:
list_node *first,**last;
uint32_t elements;
public:
};
Memory is probably a namespace (kind of like an outer class) in which SqlAlloc is defined.
C++ has both public and private inheritance (protected, too, actually.) public inheritance is just like Java inheritance; in private inheritance, though, code outside the derived class doesn't know about the base class. It's a way to inherit implementation without inheriting type. In Java, you can only do both.
memory is either a namespace or a class (struct). public means that all member functions and member data which were declared in SqlAlloc class(struct) as public and protected will be visible in base_list as public and protected.
base_list is publicly deriving from SqlAlloc which is either a namespace-class, or nested-class, depending upon what memory is - which could be either a namespace or a class.