Я пытаюсь добавить новые функции в существующую библиотеку. Мне нужно было бы добавить новые данные в иерархию классов, чтобы у корневого класса были средства доступа для него. Кто угодно должен иметь возможность получить эти данные, только подклассы могут их установить (т.е. общедоступный метод получения и защищенный сеттер).
Я знаю, что для обеспечения обратной совместимости я не должен делать ничего из следующего (список включает только действия, относящиеся к моей проблеме):
Я могу придумать два способа добавить эти данные в иерархию: добавление новой переменной-члена в корневой класс или добавление чисто виртуальных функций доступа ( чтобы данные можно было хранить в подклассах). Однако для обеспечения обратной совместимости я не могу сделать ни то, ни другое.
Библиотека широко использует идиому pimpl , но, к сожалению, корневой класс, который я должен изменить, не использует эту идиому . Однако подклассы используют эту идиому.
Теперь единственное решение, которое я могу придумать, - это моделирование переменной-члена с помощью статической хеш-карты. Так что я мог бы создать статическую хеш-карту, сохранить в ней этот новый член и реализовать для него статические аксессеры. Примерно так (в псевдо-c ++):
class NewData {...};
class BaseClass
{
protected:
static setNewData(BaseClass* instance, NewData* data)
{
m_mapNewData[instance] = data;
}
static NewData* getNewData(BaseClass* instance)
{
return m_mapNewData[instance];
}
private:
static HashMap m_mapNewData;
};
class DerivedClass : public BaseClass
{
void doSomething()
{
BaseClass::setNewData(this, new NewData());
}
};
class Outside
{
void doActions(BaseClass* action)
{
NewData* data = BaseClass::getNewData(action);
...
}
};
Теперь, хотя это решение может работать, я считаю его очень уродливым (конечно, я мог бы также добавить нестатические функции доступа, но это не устранило бы уродство).
Есть ли другие решения?
Спасибо.