У меня есть функция контроллера, которая заботится о ряде объектов, все конкретные классы которых являются производными от чистого виртуального класса.
class Abstract {
public:
virtual bool ReadyForWork() = 0;
virtual void DoWork() = 0;
};
Тогда у меня есть следующее:
class Specific : public virtual Abstract {
public:
bool ReadyForWork();
void DoWork();
};
Программа создает экземпляр Specific и присваивает его пустому указателю в цепочке.
vChain->Append(new Specific());
Все идет нормально. Когда функция контроллера срабатывает и пытается получить доступ к конкретной реализации виртуальных функций Abstract, хотя... фу.
Конкретный объект есть, я могу получить доступ к его содержимому, приведя внутреннюю пустоту* vChain к Specific*, и все это проверяется, так что плохая память не является проблемой. Но в тот момент, когда я привожу void* к Abstract*, компилятор теряет ссылки на реализации Specific, изменяя адреса функций на что-то совершенно отличное от того, что было раньше, даже несмотря на то, что указатель на сам объект правильный. Пытающийся
// ...
Abstract *vWorkObj = (Abstract*)vChain->GetObj();
if (vWorkObj->ReadyForWork()) {
// ...
приводит к следующему в моем лице:
Unhandled exception at 0x00000054 in Proj.exe:
0xC0000005: Access violation executing location 0x00000054.
Но если я сделаю это вместо этого
// ...
Abstract *vWorkObj = (Specific*)vChain->GetObj();
if (vWorkObj->ReadyForWork()) {
// ...
он работает без сбоев. К сожалению, это мне мало помогает, так как будет несколько классов, наследуемых от Abstract.
Я пробовал что-то подобное в проекте проверки концепции, и все прошло гладко:
// ...
bool ReadyForWork(Abstract *pObjPtr) {
// ...
// ...
Specific *vObj = new Specific();
if (ReadyForWork(vObj)) {
// ...
По-видимому, компилятору не нравится разрешать наследование классов во время выполнения. Есть ли способ получить доступ к наследнику абстрактного класса без явного указания компилятору, какой это наследник?
Я подозреваю, что приведение к void* и обратно может быть причиной того, что компилятор теряет ориентацию, но это избавило бы от некоторых хлопот, если бы цепочка могла быть максимально универсальной.
Я использую VS2013 Express для рабочего стола Windows. Спасибо за ваше время.