Во-первых, вопрос очень похож на
общий указатель на производный класс с дополнительными функциями, где есть хорошие ответы. Но я хотел бы получить объяснение, почему это допустимо (или нет) и когда не используются общие указатели. Так :
class Base { /* ... */ };
class Derived : public Base
{
public:
void additionnalFunc(int i){ /* access Base members */ }
};
int main(){
Base b;
Derived* d = (Derived*) &b; // or static_cast ?
d->additionnalFunc(3); // works ok.
}
Это работает, как и ожидалось с GCC. Итак, мой вопрос, это безопасно / действительно? с любым компилятором или архитектурой? если нет, то почему?
Чтобы объяснить, почему этот вопрос, вот контекст.
Так что, если приведенный выше трюк действителен, это может быть хорошим решением … Но, может быть, есть лучший дизайн для решения этой проблемы?
Это неопределенное поведение. «Работает» ли это на каком-либо конкретном компиляторе, возможно, не в этом дело; Вы не можете полагаться на эту работу в целом.*
В описанном вами сценарии кажется, что лучшим решением будет просто создать несколько бесплатных функций, которые Base
в качестве аргумента. Конечно, если требуемая функциональность зависит от protected
участники, тогда у вас есть проблемы! (И я не уверен, что есть хорошее решение, кроме как найти способ избежать такого доступа.)
* И это правда, даже если вы никогда не меняете свой компилятор. Компилятор может предположить, что весь код «правильный», поэтому небольшое изменение в вашем коде может вызвать оптимизацию, которая сделает вышеуказанный трюк бесполезным.
(Конечно, я не собираюсь предполагать, что это будет определенно случиться только потому, что это мог.)
Других решений пока нет …