'Multiple Inheritance, each derived classes can override a operator from the base class and at the same time overwritten operator declared final
My Goal is to declare final
for the few/selected overwritten operator
/member function
.
BaseClass.h
class BaseClass { public: virtual void baseClassOperator() = 0; }
DeriveOneClass.h
class DeriveOneClass : public BaseClass { protected: int varOne; public: virtual int deriveOneClassOperator(); void baseClassOperator() final override; //REM; note: the keyword final here. }
DeriveTwoClass.h
class DeriveTwoClass: protected DeriveOneClass, public BaseClass{ public: virtual int deriveOneClassOperator() overrride; void baseClassOperator() final override; //REM; And also in this line we //REM; declared this operator as //REM; final, so, no derived //REM; classes could override it. //REM; however this will create a //REM; conflict between the //REM; `DeriveOneClass` and //REM; `BaseClass` implemented operators. //REM; The `DeriveOneClass` had a //REM; final operator but //REM; the `BaseClass` had a //REM; pure virtual operator. //REM; what are the solution/fix? }
So then, when we want to have this "DeriveOneClass or DeriveTwoClass" as a Base class to the other classes, then we should not be able to override the declared final operators of those both specified classes. Similar to this syntax below;
DeriveThreeClass.h
class DeriveThreeClass : public DeriveOneClass { public: virtual int deriveOneClassOperator() override; //void baseClassOperator() override; //REM; ERROR: cannot be overwritten //REM; because 'FINAL' was declared //REM; found at super/parent class }
So we could isolate/secure the operator(s) that are define and declare final, if we instantiate this as polymorphism;
BaseClass* bc = new DeriveThreeClass();
bc->baseClassOperator(); //REM; This one will invoke/call the
//REM; DeriveOneClass overwritten baseClassOperator
//REM; or am I wrong?
However, sometime, we want to have those operators of base classes at the same time; such as the syntax example of DeriveTwoClass
with two base classes, which are the DeriveOneClass
and BaseClass
. So when we have this syntax;
DeriveOneClass* doc = new DriveTwoClass();
doc->deriveOneClassOperator();
doc->baseClassOperator();
BaseClass* bc = doc;
bc->baseClassOperator();
For all of these syntaxes, are they possible?
Solution 1:[1]
What I've got looks like this:
class InterfaceOne {
public:
void run() final { this->func(); }
protected:
virtual void func() = 0;
}
class ClassOneHelper : public InterfaceOne {
public:
void func() final override;
}
class ClassTwoHelper : public InterfaceOne {
public:
void func() final override;
}
class ClassOne : public ClassOneHelper {
protected:
auto fieldOne;
}
class ClassTwo : public ClassOne, public ClassTwoHelper {
}
And Then create a polymorph-instance:
InterfaceOne* iOne = new ClassTwoHelper();
iOne->run(); // (public access-modifier)
iOne->func(); // call only at inherited rule (protected access-modifier)
WARNING: There's a problem, When we try to create a direct-instance of ClassTwo
or ClassOne
and calling the inherited operator, the compiler will complain: saying it is AMBIGIOUS
.
This Instance didn't know which operator to use/invoke, For the reason that this Child Class has a sever-repeated/duplicated inheritance from
ClassTwoHelper
and From indirectClassOneHelper
ofClassOne
.ClassTwo* cTwo = new ClassTwo(); cTwo->run(); // ERROR: Ambigious cTwo->func(); // ERROR: Ambigious // figure 2.0
In other words if you want this option;
// this child class is free on inheriting `ClassTwo` however it must not override `func()`
class ClassMalicious : public ClassTwo {
public:
void func() override; // this func cannot be over written
}
Then never call inherited members created by a direct instance show in figure 2.0
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |