Which protected variable used in inheritance? - c++

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; }

Related

What can possible use of making a class friend and inheriting it also?

I was going through one of my local libraries and noticed the follwowing:
class Derived : public Base
{
friend class Base; // serves as a factory
protected:
pthread_spinlock_t allocLock;
bool isSafe{ true };
Derived();
char *funcA() override;
public:
void funcB( bool _in ) override;
virtual ~Derived();
};
I am not able to understand if Base has been inherited then why it has been made a friend of Derived. Also how the comment serves as a factory make sense here?
If it were to access Base function, :: operator would have been sufficient.
Is it more related to Design approach?
Making the base class a friend gives the base class access to the private members of the derived class. It is hard to tell what the reason for this is here without seeing the definition of class Base. The comment seems to indicate that the base class has member functions to create objects of the derived classes.
Generally, this is bad design. It is a bad thing when the base class knows about its derived classes at all, and it is even worse when it has access to the derived classes' private members. The dependencies should only go one way: derived classes depend on the base class, not the other way around. In other words, a change in the derived class should not break the base class.
If you need a factory, the right way to do this is to put the creation logic into a separate factory class, not into the base class.

C++: Creating derived class that has access to private variables of base?

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
}
};

overriding super class member

I am trying to inherit a class defined in a public library while overriding some of its functions and member types and I have a few questions:
None of the functions are declared as virtual in the super class so is it still ok to override these functions?
Can I override member variables by simply declaring a variable with the same name but a different type. Is this the same as hiding?
Also, if 2 is possible, then can I do the following:
public class A {
public:
class Member {
Member (//some params) {};
}
}
class B : public A {
public:
class Member : public A::Member {
Member () :
A::Member(//some params)
{
// Some additions to B::Member
}
}
}
Note: Since I cannot change the superclass templating is out of the question.
If you hide the base class's functions - you can't override them as they're not virtual - you have to keep in mind that certain scenarios like calling via pointer or reference to the base class will not work as expected and might yield "interesting" results. You'll also run into issues if the destructor is non-virtual and you're trying to destroy the derived object via a pointer to base class.
You'd be hiding the base class's member of the same name, but again it is very likely that it will not do what you expect. The base class implementation will still reference the base class's member, while the derived class's implementation will reference the derived class's member.
No.
You might want to look into wrapping the "base" class instead of trying to derive from it.
you override virtual functions. if it is not, you are hiding.
it is name hiding.
no you can not.
No, you can't override them. It will be simply hiding them.
It's not overriding, it is hiding.
You can't.

C++ | Reusing protected member of the Base class

Suppose I have a Base & Derived class:
class Base{
private:
int* _privateIntPtrB;
protected:
int* _protectedIntPtrB;
public:
//methods which use
//_privateIntPtrB and _protectedIntPtrB
class Derived: public Base{
private:
int* _privateIntPtrD;
protected:
int* _protectedIntPtrB; //I am redeclaring this var
public:
//methods which use
//_privateIntPtrD and _protectedIntPtrB
My question:
In the methods of the Derived class, does the Derived version of _protectedIntPtrB get used? (I think it does, but want to confirm).
If a method is not redefined by the Derived class, which version of the _protectedIntPtrB will be used by a pointer to Derived class?
The reason I am asking - I want to initialize _protectedIntPtrB in the Derived class differently and want that version of the _protectedIntPtrB to be used in all the instances of Derived class.
In the methods of the Derived class, does the Derived version of _protectedIntPtrB get used?
Yes, it hides the base class member and so an unqualified use of _protectedIntPtrB in the scope of Derived refers to Derived::_protectedIntPtrB. (The base class variable is still available, if qualified as Base::_protectedIntPtrB).
If a method is not redefined by the Derived class, which version of the _protectedIntPtrB will be used by a pointer to Derived class?
The base-class variable. Data members of derived classes are not available from the base class.
The reason I am asking - I want to initialize _protectedIntPtrB in the Derived class differently and want that version of the _protectedIntPtrB to be used in all the instances of Derived class.
Usually, the best way to make derived classes behave differently to their base classes is by overriding virtual functions. It would probably be better if you had a think about exactly what you want to achieve: work out what behaviour you want to modify, and encapsulate that in a virtual function.

Why does a purely virtual/abstract class require a constructor, in particular for protected const member variables?

I have a purely virtual class defined as such:
class BaseClass {
protected:
const int var;
public:
void somefun() = 0; // what I mean by a purely virtual class
// stuff...
};
If I don't add a constructor defined as such:
BaseClass(const int & VAR) : var(VAR) {};
that I would have to subsequently use in ever derived class, my derived class can't initialize the const variable var to whichever value it wants to. Now I actually understand what's going on here. Before constructing a derived class, a constructor of the base class is called, at which point const member variables must be initialized. My question is not a "how do I make my code work" kind of question, that's already been done. My question is about why the compiler thinks it's necessary. For a purely virtual class, shouldn't I be allowed to write something like:
class DerivedClass : BaseClass {
public:
DerivedClass() : var(SOME_VALUE) {};
}
If the compiler knows that a call to a BaseClass constructor will necessarily be followed by a call to some derived class constructror (since an object of abstract type can never be instantiated) shouldn't it give us a bit more leeway?
Is this all a consequence of how C++ chooses to get around the Diamond problem? Even if that was the case, shouldn't the compiler at least somehow allow for the possibility that const member variable of purely virtual functions will be defined in derived classes? Is that too complicated or does that mess with the C++ solution to the Diamond problem?
Thanks for the help everyone.
It's not "purely virtual" (whatever you mean by that) - it contains a data member.
Class members can only be initialised by the initialiser list of a constructor of that class, not of a derived class. That's how object initialisation is specified: all members that are initialised, are initialised before the constructor body begins.
Constant objects must be initialised, since they can't be assigned a value later.
Therefore, a class with a constant data member must initialise it in each constructor.
For a purely virtual class, shouldn't I be allowed to write something
like
No, but you can(and in this case should) write something like this:
class DerivedClass : BaseClass {
public:
DerivedClass() : BaseClass(SOME_VALUE) {};
};
The construction of an object occurs in a specific order. The base class must be fully constructed before the constructor of a derived class is run, so that the derived constructor is working with a fully formed and valid base object. If the initialization of base member variables were put off until the construction of the derived class, this invariant would be broken.