Я уже давно смотрю на stackoverflow и google, но не могу найти ответ на свой конкретный вопрос о циклических ссылках, неполных типах и полиморфизме.
Я надеюсь, что смогу объяснить этот вопрос без публикации большого количества кода, но если я потерплю неудачу, пожалуйста, дайте мне знать, и я постараюсь написать простой пример.
У меня есть 2 класса, которые оба используют друг друга (скажем, класс COne и CTwo). Кроме того, класс COne имеет базовый класс (скажем, BaseOne).
Я использую средства защиты заголовков (если вы их так называете) и неполные типы, чтобы «решить» проблему циклических зависимостей.
в заголовочных файлах сверху:
#pragma once
и где-то вверху в файле C ++ для CTwo:
class COne;
Теперь я сталкиваюсь с проблемой, заключающейся в том, что из-за неполного типа компилятор, похоже, не знает, что COne является производным от BaseOne.
Поэтому в функции с возвращаемым типом BaseOne * я хочу вернуть COne *, что должно быть возможно, потому что это унылый код, но в нем говорится, что они не одного типа.
Я исправил это сейчас, используя приведение в стиле C
return (BaseOne*)m_c_one;
Я хотел спросить: есть ли лучший способ решить эту проблему, чем использовать приведение в стиле C?
Приведение в стиле C небезопасно, поскольку не гарантируется, что COne
объект и его BaseOne
подобъект имеет одинаковый адрес памяти (это гарантируется, если COne
является классом стандартной компоновки (9p7), но это, как правило, исключает полиморфизм).
Нужен компилятор COne
быть завершенным, чтобы выполнить приведение (3.2p5), потому что COne
может использовать виртуальное или множественное наследование, и вообще, потому что полиморфные классы не обязаны иметь простую структуру памяти.
struct COne: BaseZero, BaseOne { ... };
struct COne: virtual BaseOne { ... };
Вам придется либо переместить приведение к точке в исходном файле, где определение COne
доступно, или напишите свою собственную функцию приведения BaseOne *to_base(COne *)
с реализацией в точке в исходном файле, где определение COne
доступен.
Других решений пока нет …