Существует прямая структура C, объявленная в немодифицируемом заголовке. Я хотел бы «виртуально» добавить к нему удобные функции-члены. Очевидно, что моим первым выбором было бы расширение структуры и добавление методов в производный класс. Не могу, так как сама структура объявлена как "вперед" в заголовке, поэтому я получаю сообщение об ошибке "ошибка: недопустимое использование неполного типа...". Я получаю аналогичную ошибку, если пытаюсь определить новую структуру с одним элементом старой структуры. Это отстой.
Тем не менее, я подумал, что могу немного поэкспериментировать с reinterpret_cast, чтобы заставить его работать. Вот как это будет выглядеть:
//defined in header
struct A forward;
void do_something_with_A(A* a, int arg);
//defined in my wrapper
struct B {
B* wrap(A* a) {return reinterpret_cast<B*>(a); }
void do_something(int arg) {do_something_with_A(reinterpret_cast<A*>(this),arg); }
}
Если бы я добавил неявные преобразования из типа B в тип A, я думал, что это могло бы работать почти, как если бы B был наследником A с нулевыми данными. Однако это, очевидно, поднимает вопрос: это не определено в С++? Обычно я думаю, что доступ к элементу незаконно приведенной структуры будет неопределенным; это имеет смысл. Тем не менее, я думаю, что было бы хорошо переинтерпретировать_приведение из одного типа в другой, передавая этот указатель, а затем снова возвращая его, не делая ничего незаконного между ними. Я также думаю, что способ, которым компилятор реализует невиртуальные члены структуры, будет создавать функцию
B::do_something(B* b, int arg)
и вызывая это с соответствующим аргументом для B. Затем это сводится к предыдущему случаю, который по моей сомнительной логике в порядке. Поэтому я думаю, что вызов .do_something для структуры, которая на самом деле является reinterpret_cast A, будет в порядке.
Однако это ничего не говорит о том, что на самом деле говорит стандарт C++ по этому вопросу. Любая помощь с этим? Кроме того, если у кого-то есть информация о том, насколько хорошо это будет работать на практике (т. Е. «Каждый когда-либо созданный компилятор принимает это» или «это работает только с несколькими компиляторами»), это также было бы полезно, но немного меньше.
static_cast
здесь, если вы не добавите соответствующее преобразование в классB
, то есть конструктор, который принимаетA*
. В любом случае, либо указательA
не несет никакой информации, что означает, что он не имеет значения. Или же он несет некоторую информацию, и в этом случае вы находитесь вreinterpret_cast
и UB земле, возможно, подходит для вашего компилятора, возможно, нет. - person Cheers and hth. - Alf   schedule 24.08.2011struct
s без элементов данных по-прежнему имеют размер 1. - person Chris Lutz   schedule 24.08.2011