Приветствую!
Есть класс A
class A: public InterfaceA
{
A() {}
...
void f() { qDebug()<<"fA"; }
}
Наследуется от чисто виртуального InterfaceA:
class InterfaceA
{
virtual void f()=0;
}
Дальше начинается мне непонятное:
A * clA = new A();
InterfaceA * iA = clA;
typedef InterfaceA * TIA;
void test(const TIA & I ) {
//-- здесь "I" имеет не верный адрес, всегда на 10 больше, чем до вызова
}
test(iA);
Теперь вопросы:
1. Почему при вызове test указатель по ссылке подменяется, и почему именно на 10 больше?
2. Поправка - не приходит: Почему, если сделать вместо iA = clA каст iA = static_cast(clA); поведение приходит в норму?
3. Я думал, что явного приведения при даунгрейде класса не требуется, я не прав?
4. Какие могут быть последствия, ведь если написать iA.f() вызов будет корректен ?
5. Если такое приведение не является безопасным, почему компилятор не выдал предупреждения или вообще ошибки?
UPDT1:
Выяснил, что если класс A наследуется от QObject, то при
A * clA = new A();
то в дебагере при просмотре переменной clA адрес у QObject будет например
0x9d6c78, а адрес InterfaceA
0x9d6c70 и самой переменной clA адрес будет
0x9d6c78
Если сделать InterfaceA * iA =static_cast(clA); адрес переменной iA будет
0x9d6c70 О_О
это при условии, что класс A объявлен как: public QObject, public InterfaceA
UPDT2:
Выяснилось, что вышеперечисленная особенность происходит не сразу, а спустя некоторое количество действий и внутри шаблонной магии Qt, выясняю где.
UPDT3:
В общем почему я это всё затеял - пытался отловить странный баг (сегфолт в недрах qml, куда отладчиком не подлезть).
Почему меняется указатель: скорее всего из-за множественного наследования + приколы Qt.
По багу поиск решения в процессе:
QVariant при заполнении приватной структуры data пытается заполнить поле QObject * o, но обламывается т.к. приведение типов не проходит (указатель то не тот), и когда где-то в программе (скорее всего в недрах qml) нужно сделать variant.value() то ловится сегфолт.
Осталось найти где именно идёт заполнение и как-то поспособствовать правильному касту.
Почему он считает, что InterfaceA наследуется от QObject - я его заставил, что бы работало int idd= QMetaType::type("InterfaceA*"); void *myClassPtr = QMetaType::create(idd);