Ниже приведена структура классов (подробности опущены).
Environment.h
#include "SimEnv.h"
class Environment : public SimEnv {
public:
virtual int functionA(int arg) {
printf("I'm in functionA\n");
. . .
}
virtual int functionB(int arg) {
printf("I'm in functionB\n");
. . .
}
};
DerivedEnv.h
#include "Environment.h"
class DerivedEnv : public Environment {
public:
DerivedEnv(GrandParentClass* grandpaClass) : Environment() { . . . }
};
ParentClass.h
#include "GrandParentClass.h"
#include "Environment.h"
class ParentClass : public GrandParentClass {
public:
ParentClass() {
printf("In ParentClass constructor\n");
m_pEnv = new DerivedEnv(this);
m_pEnv->functionB(val);
}
protected:
Environment* m_pEnv;
virtual void thisFunct() {
printf("Calling functionB from ParentClass::thisFunct()\n");
m_pEnv->functionB(val);
}
};
DerivedClass.h
#include "ParentClass.h"
class DerivedClass : public ParentClass {
public:
DerivedClass() : ParentClass() {
printf("In DerivedClass constructor\n");
m_pEnv->functionB(val);
}
void thatFunct {
printf("Calling functionB from DerivedClass::thatFunct()\n");
m_pEnv->functionB(val);
}
void sim() {
thisFunct();
printf("Calling functionB from DerivedClass::sim()\n");
m_pEnv->functionB(val);
}
};
main.cc
#include "DerivedClass.h"
void main() {
. . .
static DerivedClass derivedClass;
derivedClass.sim();
. . .
}
Проблема, с которой я столкнулся, заключается в том, что когда я запускаю свой код и создаю экземпляр DerivedClass, я получаю следующее:
In ParentClass constructor
I'm in functionB
In DerivedClass constructor
I'm in functionA
Calling functionB from ParentClass::thisFunct()
I'm in functionB
Calling functionB from DerivedClass::sim()
I'm in functionA
Итак, моя программа вызывает правильную виртуальную функцию в конструкторе ParentClass, но неправильную функцию сразу после этого в конструкторе DerivedClass. Это то, что я проверил до сих пор:
- Я убедился, что проблема не в том, что моя сборка сломана.
- Я распечатал vtable в gdb, используя
p /a (*(void ***)m_pEnv)[0]@30
в конструкторе ParentClass и в конструкторе DerivedClass. Обе таблицы показаны одинаково
Я искал в интернете, и кажется, что такие проблемы могут быть связаны с повреждением стека. Это правда? Как я могу отладить это? Есть ли другое объяснение этой проблемы.
Добавление
Я продолжил отладку и понял, что здесь есть проблема контекста. Когда я вызываю functionB из любой функции-члена ParentClass, он выполняет ее правильно.
Похоже, что именно из DerivedClass вызовы идут не в ту функцию.
Я изменил псевдокод, чтобы выделить это.