1) W prostych przypadkach można po prostu utworzyć wrapper C interfejsu (zbudowany bez RTTI). Następnie możesz użyć interfejsu C w programach obsługujących RTTI, pod warunkiem, że traktujesz je jako abstrakcyjne typy C z twojego programu obsługującego RTTI.
2) Kompilowanie biblioteki z RTTI jest dokładnie tym, co powinno wykonać (lub na żądanie dostawcy), chyba że istnieje bardzo dobry powód, aby wyłączyć RTTI (np. Pracujesz w domenie, w której wyjątki nie powinny być używane, takie jak jądro, sterowniki lub jakaś inna strefa wyjątkowa - lub gdzie pamięć jest ciasna).
3) Zmień bibliotekę tak, aby nie używała funkcji dynamic_cast, wyjątków, operatora typu, lub cokolwiek innego, co powoduje problem i odbudowuje go przy wyłączonym RTTI. Podobnie jak 1, możesz uczynić to oddzielną biblioteką abstrakcji, w zależności od organizacji programu.
4a) Następną opcją jest nigdy nie odwoływać się do informacji o typie obiektu (np. Nie dynamic_cast ani nie wyrzucać go) - a to może być uciążliwe. Spowoduje to usunięcie błędów linkerów w informacjach o typie referencyjnym.
4b) Najłatwiej jest stworzyć wewnętrzną klasę (przypuśćmy, że istnieją metody, które musisz przesłonić, i są typy, które musisz połączyć z programami zależnymi od rtti). Możesz utworzyć typ (inner
), który dziedziczy po typie swojej biblioteki i wykonuje niezbędne przesłonięcia, ale następnie wywołuje zwrotnie przez inną hierarchię klas (druga hierarchia może dowolnie używać rtti). Teraz wirtualne eksporty klasy inner
są umieszczane w jednostce tłumaczeniowej z rtti wyłączonym (ponieważ inaczej niejawnie odwołają się do informacji o typie klasy podstawowej). Następnie możesz łatwo poddać kwarantannie zależność od informacji o typie i zbudować hierarchię, która używa rzeczy takich jak wyjątki - ta hierarchia używa tego typu jako wartości. Oczywiście, , jeśli działa to, to cała implementacja zdefiniowana - trzeba zrozumieć, w jaki sposób RTTI i vtables są skonstruowane dla twoich docelowych platform (patrz dane ABI). Nawet pominięcie RTTI jest odchyleniem od standardowego C++. Nie ma informacji, które stwierdzałyby, że obecność symbolu spowoduje prawidłową konstrukcję twoich vtables i wpisanie informacji o bazie, która została skompilowana bez tych cech.
Powiedziałeś, że 1 i 2 są twoimi bezpiecznymi opcjami, 3 jest domeną rozszerzenia platformy bez sejfu (bezpieczne), a 4 jest podejściem, które może działać na nie lub tylko na niektórych systemach.
Ilustrowanie 4b
class MyClass // << cast me. throw/catch me. get my mangled name,
// but put my family's virtual exports in a TU with RTTI enabled
: public MyRTTIEnabledFamily {
public:
MyClass() : d_inner(*this) {}
virtual ~MyClass();
private:
void cb_onEvent(NetlinkEvent * evt) {
// no-rtti suggests exceptions may not be available,
// so you should be careful if your program throws.
someInfo = evt->getInfo();
}
private:
// non-rtti hierarchy
class t_inner : public NetlinkListener {
public:
t_inner(MyClass& pMyClass) : NetlinkListener(), d_myClass(pMyClass) {
}
virtual ~t_inner(); // << put your virtual exports in a TU with RTTI disabled.
// one out of line virtual definition is necessary for most compilers
private:
virtual void onEvent(NetlinkEvent * evt) {
// how the callback to your imp actually happens
this->d_myClass.cb_onEvent(evt);
}
private:
MyClass& d_myClass;
};
private:
t_inner d_inner; // << don't do anything with my type info -- it does not exist.
};
Czy możesz podać przykładowy kod opisujący sposób, w jaki próbujesz dokonać podklasy nadklasy? – Tuxdude
@Tuxdude Dodano nagłówki. Nie ma implementacji podklasy (tylko stubs). Kod dla super klasy to ASOP typu open source. –