I am currently studying c++ and I have a question.
Inside the concept of inheritance, I understand that the subclass has the access to base class's data and method.
But if the Base class implements an interface, can the subclass access or use the methods defined in the interface that is implemented in the Base class?
Yes, you can do this. Suppose you have a Base class as following
class Base {
public:
virtual void someMethod() {
//Do your stuff
}
};
And a derived class like the following
class Derived : public Base {
public:
void someMethod() override;
};
And the definition of someMethod in Derived class is as following
void Derived::someMethod() {
// Do Derived Stuffs
//Now you may call the Base::someMethod by following
Base::someMethod();
}
You can try in this way.
Related
I would like to create a thin host class of a specific class to extend a specific functionality but not necessarily inheriting it. For example, class Base is described as:
class Base
{
public:
void func_1();
void func_2();
...
void func_n();
};
class Base1 will inherit Base but store a pointer of Base
class Base1 : public Base
{
public:
void func_1()
{
mpBase->func_1();
// do something else
}
private:
Base* mpBase;
}
Is there a way to automatically invoke mpBase->func_2 to func_n for Base1 because they are basically the same (n can be a large number)? Using pointer it is not done automatically. The reason I want to do it because I want to extend func_1 for all possible inherited classes of Base, without creating Base1 for every inherited classes.
Best
I have to make a base class with one derived class in C++. In the end I need to evidence polymorphism between 2 methodes void Read and void Show.
After I did this, I have to create an abstract class Object from which the base class will be derived.This class will contain just pure virtual methods Read and Show.
I don't think I fully understand this. So I make an abstract class Object where I put these 2 methods with "=0" to mke them pure. But this means that I have to edit the base class also, to make it derived from class Object? Like, before:
class Base {
}
after
Class Base : public Object
Can someone make me understand?
You're on the right track. In your Base class, you can mark methods virtual that you intend to be polymorphic. You can set the functions = 0 if they are "pure virtual" and have no implementation in the base class, and are required in any concrete derived class.
class Base
{
public:
virtual void Read() = 0;
virtual void Show() = 0;
};
Then for your derived class you had the syntax backwards. Note that the override keyword indicates that you are overriding a virtual method from the base class. This keyword enforces that the function signature matches the one from a base class.
class Object : public Base
{
public:
void Read() override; // implement this
void Show() override; // implement this
};
The usage could look like the following. Note that you instantiate an Object but carry a pointer to a Base*. Due to polymorphism, the derived implementations are invoked.
int main()
{
Object obj;
Base* p = &obj;
p->Read(); // due to polymorphism will call Object::Read
p->Show(); // due to polymorphism will call Object::Show
}
How would I do so without making base method virtual?
class Base {
public:
bool foo() const;
}
class Derived : public Base{
public:
bool foo() const;
}
There is no any sense to call isEmpty of a derived class from isEmpty of the base class because the base class knows nothing about its derived classes. Take into account that the base class is single while there can be numerous derived classes. So of what derived class are you going to call function isEmpty?
There is sense to call isEmpty of the base class in a derived class. it can be done the following way
bool Derived::isEmpty() const
{
return Base::isEmpty();
}
You cannot. That's why there is a virtual keyword. If your class forbids use of this keyword, I'd rather not use it as a starting point to learn OOP.
If you really need this, you can store a null pointer to a function with the foo's signature in your base class instances, and use the base implementation until this pointer is null. Then you can change this pointer in your derived class and associate is with your derived implementation. Then your base class can call that function via the pointer.
Below is some schematic code for this:
class Base {
public:
bool foo() const {
if (NULL == internalFoo) {
// base implementation;
} else {
return internalFoo();
}
}
private:
bool (*internalFoo)() = NULL;
}
class Derived : public Base{
public:
bool foo() const;
}
I don't understand why the compiler doesn't like this, here is and example of the problem:
class A
{
public:
virtual void Expand() { }
virtual void Expand(bool flag) { }
};
class B : public A
{
public:
virtual void Expand() {
A::Expand(true);
Expand(true);
}
};
When I try to compile this the A::Expand(true); compiles fine, but the non scoped Expand(true); gets this compiler error:
'B::Expand' : function does not take 1 arguments
You don't need virtual methods for that behaviour. Methods in a derived class hide methods with the same name in the base class. So if you have any function named Expand in your derived class (even if it is an override of a virtual method from the base class), none of the base classes methods with the same name are visible, regardless of their signature.
You can make the base classes methods visible with using. For that you would add using A::Expand; to the definition of B:
class B : public A
{
public:
using A::Expand;
virtual void Expand() { Expand(true); }
};
That's because besides overriding the base Expand(), you're also hiding the base Expand(bool).
When you introduce a member function in a derived class with the same name as a method from the base class, all base class methods with that name are hidden in the derived class.
You can fix this by either qualifying (as you have) or with the using directive:
class B : public A
{
public:
using A::Expand;
virtual void Expand() {
A::Expand(true);
Expand(true);
}
};
The non-virtual interface idiom describes how the virtual methods are nonpublic customisation points, and public methods are nonvirtual to allow the base class to control at all times how the customisation points are called.
This is an elegant idiom and I like to use it, but how does it work if the derived class is a base class in itself
It works, because the derived class can override a private virtual function of a base class, even if the base class function overrides its base class function.
This is perfectly legal:
class Parent
{
public:
int foo() {return bar();} // the non-virtual public interface
private
virtual int bar();
};
class Child : public Parent
{
private:
virtual int bar(); // overrides Parent::bar()
};
class Grandchild : public Child
{
private:
virtual int bar(); // overrides Child::bar();
};
The derived class can decide for itself:
You can just override the method completely by implementing the virtual function.
You can augment the method by calling the 'middle' classes function at some point in your derived class method.
If that's not what you want, you need to set it up explicitly in the 'middle' class. I wouldn't though. If you find yourself desiring this, it probably means you didn't give the base class enough customization points.