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.
Related
I want to call a derived class function that isn't defined in the base class using base class pointers. but this always raises the error:
error C2039: ‘derivedFunctionName’ : is not a member of ‘BaseClass’
Do you know how I could get around this?
Thanks,
You can't call a member that appears only in a derived class through a pointer to the base class; you have to cast it (probably using dynamic_cast) to a pointer to the derived type, first -- otherwise the compiler has no idea the method even exists.
It might look something like this:
void someMethod(Base* bp) {
Derived *dp = dynamic_cast<Derived*>(bp);
if (dp != null)
dp->methodInDerivedClass();
}
One way is to make the function virtual in the base class and then override it in the derived class. You don't have to define the function in the base class (although you can), but you can use the pure virtual syntax in the base class virtual void foo() = 0; if you don't want to provide an implementation in the base class.
This will let you override it in the derived class and still call it in the base class through a base class pointer. This is known as 'polymorphism'.
You can also just cast it to a derived type at run time if you are sure it is actually a derived class pointer at that time. If it is not, it will crash.
You can call a derived class member through a pointer to a base class as long as the method is virtual. That's what polymorphism is about.
In order for that to work you must declare a virtual method (probably pure virtual) in the base class and overload it in the derived class.
Note that you will run into issues calling the derived member from the base method. Do some ARM or Meyers reading if this doesn't make sense to you.
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 am trying to run the following code but getting error.
#include <iostream>
template <typename T>
class Base {
public :
static T& Get() {
static T t;
return t;
}
};
class Derived : public Base<Derived> {
private :
Derived() {}
// friend Base<Derived>; //un-commenting this will make code work.
};
int main() {
Derived& d = Derived::Get();
return 0;
}
Error :
prog.cpp: In instantiation of ‘static T& Base::Get() [with T = Derived]’:
prog.cpp:18:24: required from here
prog.cpp:7:14: error: ‘Derived::Derived()’ is private within this context
static T t;
^
prog.cpp:14:4: note: declared private here
Derived() {}
^~~~~~~
I have following questions
class Derived is publically derived from class Base, doesn't it makes Get() a member function of Derived too ?
If [1] is true, and Get() becomes a member function of Derived, then
why it's not able to call the private constructor of Derived.
Assume we have multiple classes to be implemented as Singleton, is
there a way we can do it using templates with something similar to
the above example? (additional question)
I understand :
We can make the above code work by making base a friend of derived
line to the code.
We can make Get() as "non static virtual function" and override in
the derived classes.
I am not looking for the above mentioned solutions. Though, please let me know if this(these) is(are) the only possible solutions to achieve this kind of design.
class Derived is publically derived from class Base, doesn't it makes Get() a member function of Derived too ?
Yes in the sense that the lookup Derived::Get() will work, but it call the very same function as if you wrote Base<Derived>::Get().
If [1] is true, and Get() becomes a member function of Derived, then why it's not able to call the private constructor of Derived.
Because different classes cannot access private members by name. This is what private is for. The same reason why Derived cannot access private members of Base.
Assume we have multiple classes to be implemented as Singleton, is there a way we can do it using templates with something similar to the above example? (additional question)
Isn't that what your example is doing?
We can make the above code work by making base a friend of derived line to the code.
Correct.
We can make Get() as "non static virtual function" and override in the derived classes.
I don't think so. You cannot call that virtual function without an object. You'd be required to create an instance of Derived before calling Get, but Get is supposed to create our object.
Though, please let me know if this(these) is(are) the only possible solutions to achieve this kind of design.
I would probably go forthe friending. Simple, concise and does what you want. There is other solutions like having a protected type in the base, and defining a public constructor that receive that protected type, but this is quite leaky and I won't recommend.
class Derived is publically derived from class Base, doesn't it makes Get() a member function of Derived too ?
No. Member functions (static and non-static) of base are member functions of base, not member functions of the derived class. However, the member functions of base(s) are looked up when invoking a member function (depending on visibility).
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; }
As far as I understand the reason that we cannot pass a derived class object to a base class reference for private inheritance is that Since Derived is privately inherited from Base, the default constructor of Base would be called before the constructor of Derived. But because it is private and not inherited to Derived, we get a compiler error.
But, if I try to create a public constructor for Base and inherit from Derived privately and then re-assign the public status to Base's constructor will it allow me to pass a derived's instance to Base reference?
I tried it as follows,
#include <iostream>
using namespace std;
class base
{
public:
base(){}
void print(){ puts("In base"); }
};
class derived : private base
{
public:
base::base; /* Throws an error - Declaration doesnt declare anything*/
void print(){ puts("In derived"); }
};
void func(base& bRef)
{
}
int main()
{
derived dObj;
func(dObj); /* Throws an error - 'base' is an inaccessible base of derived */
}
It throws an error for base::base (publicizing privately inherited constructor to public).
Is what I am trying valid? Can anyone please tell me?
The reason we cannot have a base class reference to a derived object that inherits privately is because that would violate the Liskov Substitution Principle: the derived object IS-NOT-A base class object because it does not provide the base class public interface. You cannot work around this
For this reason, private inheritance is a way of reusing implementation and not when you want to make a more specialized type. As this can most of the time be done with composition (i.e. having a member of the base class instead of privately deriving), private inheritance might be a bad code smell.
You can read here (be sure to follow all the links) for more information on when private inheritance is a good option (summary: when there simply is no other choice).
No, it is not valid to point to an object of Derived with a pointer or reference of Base class. If it were possible, then the whole purpose of private inheritance (hide the fact that the derived class inherits part (or the whole) of its functionality from the base class) would be useless.
Say you have a method foo() in the base class. You don't want this method to be called. But if it were possible to point the object from a pointer of the base class, then it would also be possible to call foo().
Base * ptrBase = &objDerived; // Let's suppose this would compile
ptrBase->foo(); // Now we can call foo() (?)
When you declare private inheritance, is as if the Derived class where not related to the base class. It is just you, the developer, the only one that should "know" that this relationship exist, and actually you should forget about it, because it just won't work.
Private inheritance is just there solely as a reusability mechanism, not as a true inheritance mechanism. It is not recommended to even use it, since you can obtain a better result by simply applying composition (i.e. just make an attribute of class Base in Derived).