Consider we have an library that contains a base class, like below,
class Base{
protected:
int a;
public:
Base(int a) : a(a) {}
};
Then, I want to extend it in a new library by adding a new function, like below
class Derived : public Base{
public:
bool is_greater(Derived &y) { return a > y.a; }
};
So that, we can compare their member values using member function is_greater
, as
int main(){
Base b1, b2 = // get from the old library's output
Derived d1 = b1, d2 = b2 // convert from base class to derived class
d1.is_greater(d2);
}
So, what's the best solution for this kind of conversion?
, performance is the most important point I am concerned about.
CodePudding user response:
Just like any other conversion. You can use a converting constructor:
explicit Derived(const Base& base): Base(base) {}
Conversion operator isn't a practical option in this case since the base doesn't know about the derived type.
CodePudding user response:
Extending a class to add functionality is only viable when either
- The class is designed to be extended that way, polymorphic with appropriate APIs, or
- You use your extended class everywhere, not the base class.
... otherwise, there is no way to avoid copies or dangerous casts with potential undefined behavior.
Regardless, I'm of the opinion that equating "extension" to "inheritance" is a code smell made popular by abuse of OOP. C has free functions. It's un-intrusive and allows you to work with the type and objects you really mean to work with. Furthermore, that protected member is still accessible if you are savvy:
bool is_greater(Base const& l, Base const& r) {
struct fetch : Base { using Base::a; };
return l.*(&fetch::a) > r.*(&fetch::a);
}
We define a local class that inherits from Base
, yes. But we don't do it to mess around with objects of the wrong type. All it does is make the member accessible to us. Then we simply use pointer-to-member syntax to access that member on our Base
objects in a well-defined manner.