Suppose I have a base class that is an abstract interface, and two derived classes, which inherit a certain state from the base class. I want to change which derived class I'm using at run-time, but I want to preserve the shared state.
class Base{
public:
virtual void abstract() = 0;
SharedState ss;
};
class Der1 : public Base{
Der1() = default;
virtual void abstract() {//bla bla};
Der1(SharedState &s){
ss = s;};
};
class Der2 : public Base{
Der2() = default;
virtual void abstract(){//bla bla 2};
Der2(SharedState &s){
ss = s;};
};
struct SharedState{
int x,y,z;
float x1,y1,z1;
//etc...
}
I my handler code, I have a smart pointer that changes behaviour based on class type at run-time, hence the shared state constructor.
//driver code
std::unique_ptr<Base> ptr = std::make_unique<Der1>();
I'm planning to change the type, but with such a constructor I can preserve the state. However it is highly annoying to preface every member of the shared state with ss.
, is there a way to avoid this, perhaps with a using declaration of some sort?
Edit: I know I can move the shared state in the base and make it static, but that leads to performance drops when I'm not using this interface.
This is an ugly answer, but is an answer, solves the "ss" problem and can be usefull.
I overloaded the operator []
to directly return the values of your struct
struct SharedState{
int x,y,z;
float x1,y1,z1;
//etc...
};
class Base{
public:
virtual void abstract() = 0;
SharedState ss;
public:
int& operator[](const std::string rhs)
{
if(rhs == "x") //Here you will manage all the struct members, probably a map
return this->ss.x; // return the result by reference
}
};
class Der1 : public Base{
void abstract() override { };
public:
Der1(SharedState &s){
ss = s;};
};
class Der2 : public Base{
void abstract() override { };
public:
Der2(SharedState &s){
ss = s;};
};
int main()
{
SharedState ss;
ss.x = 100;
std::unique_ptr<Base> ptr = std::make_unique<Der1>(ss);
std::cout << (*ptr)["x"] << std::endl;
(*ptr)["x"] = 5; // You can change it too
std::cout << (*ptr)["x"] << std::endl;
std::unique_ptr<Base> ptr2 = std::make_unique<Der2>(ptr->ss);
std::cout << (*ptr2)["x"] << std::endl;
}