I have a program which has a base class and several derived classes which contain member functions which override the base class member functions. There is some duplication of code between the derived classes which I would like to eliminate. In particular, in one of the derived classes, one member function contains some initial processing and then the same processing as the same named member function in a different derived class.
Here is a simplified example:
#include <iostream>
class BASE
{
public:
virtual ~BASE() = default;
virtual void A() { std::cout << "In BASE\n"; }
virtual void B() { std::cout << "Shared by all instances\n"; }
virtual void C() { std::cout << "Different in all instances\n"; }
};
class D1: BASE
{
public:
void A() override { std::cout << "In D1\n"; }
void C() override { std::cout << "In D1::C()\n"; }
};
class D2: BASE
{
public:
void A() override
{
std::cout << "In D2\n";
// #1
// D1::A(); // Error cannot call D1::A() w/o object
// #2
// D1 *t = (D1 *) this; // Creates recursive loop
// t->A(); // calling D2:A()
}
void C() override { std::cout << "In D2::C()\n"; }
};
int main()
{
D1 d1;
D2 d2;
BASE *b = &d1;
b->A();
b = &d2;
b->A();
}
In the example, I'd like the call to D2::A() to chain to D1::A() so I see messages from both member functions. I've tried two different ways to do this (see #1 and #2) which both get errors.
What is the correct way to do this?
First of all, you can't do
BASE *b = &d1;unless you declareclass D1: public BASE. Note the use ofpublic. Otherwise you get something like 'type cast': conversion from 'D1 *' to 'BASE *' exists, but is inaccessible. (MSVC)Furthermore, it sounds like
D2needs to be derived fromD1so thatD2::Acan callD1::Ain its implementation in addition to any extra functionality. This way you can "chain" as you mentioned by explicitly callingD1::A()at the end of the implementation ofD2::A.expected output:
The first "In D1" will come from calling
b = &d1; b->A();and the second and third messages "In D2, In D1" will come from callingb = &d2; b->A();becauseD2::Aexplicitly "chains" toD1::A.