I have a hierarchy as follows:
class Element{ public : virtual void Accept(Visitor&) = 0
protected : Element(); int num;
};
class ElementA : public Element{
public : ElementA();
void Accept(Visitor& v) {v.Visit(this};}
};
class ElementB : public Element{
public : ElementB();
void Accept(Visitor& v) {v.Visit(this};}
class Visitor{
public: void Visit(ElementA*);
void Visit(ElementB*);
};
EDIT: It is required to add the method int getNum() to the hierarchy that would provide the value of num. However, this will need that the entire hierarchy be compiled again and we are not allowed to do that. So we have to change the design of the hierarchy in a way so that the recompilation of the hierarchy is not needed.
What you want to do is not possible in a cleanly designed way. I have no idea, why a complete recompile of that hierarchy would be such a problem, but there is a solution that is technically possible without employing UB hacks like reinterpret_casting the access protection away and other hacks.
int Visitor::getNum(Element* pe)
{
//define a pick-pocket... ;)
struct ElementNumAccessor : private Element
{
ElementNumAccessor(Element const& e) : Element(e) {}
int getNum() { return num; }
void Accept(Visitor&); //has to be declared, but needs not be defined
};
//...and let him work:
ElementNumAccessor ea(*pe);
return ea.getNum();
}
This soultion in action: http://ideone.com/e1chSX
This exploits the fact that protected access is transitive, but comes at expense of a copy of each element you want the num from. I made the struct a function local class, so that nobody gets the idea to actually use it for any other purpose.
But bear in mind that this technique is a hack, an exploit of a language feature that is not meant to be used this way.
My advice would be: If your hierarchy is so entangled in the program that changing it leaves to a recompilation horror, then it's about time to refactor your program to reduce compiletime dependencies and then do the changes you have to do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With