Преобразовать указатель на элемент данных в void *

Я знаю, что могу получить указатель на член данных для класса или структуры, но последняя строка следующего кода не скомпилируется:

struct abc
{
int a;
int b;
char c;
};

int main()
{
typedef struct abc abc;
char abc::*ptt1 = &abc::c;
void *another_ptr = (void*)ptt1;
}

почему я не могу конвертировать ptt1 в another_ptr? Мы говорим об указателях, поэтому один указатель должен иметь размер, аналогичный другому (хотя концептуально другой)

6

Решение

указатель на нестатический тип члена класса это не то же самое, что тип указателя объекта; они ведут себя совсем по-другому. На самом деле, вы даже не можете разыменовать указатель на член с *, Чтобы получить доступ к члену через указатель на член, вы используете .* а также ->* операторы вместо. если ты мог приведите его к типу указателя объекта следующим образом: что произойдет, если вы разыменовываете его с помощью *?

Только указатели на объекты имеют стандартное преобразование в void* (§4.10):

Значение типа «указатель на резюме T,» где T является типом объекта, может быть преобразовано в значение типа «указатель на резюме void».

Они настолько отличаются, что стандарт даже делает все возможное, чтобы убедиться, что термин «указатель» не включает указатели на нестатические элементы (§3.9.2):

За исключением указателей на статические элементы, текст, ссылающийся на «указатели», не относится к указателям на элементы.

10

Другие решения

Основная причина в том, что нет требования
указатель на член имеет тот же размер и представление, что и
указатель на данные. На практике трудно представить указатель
чтобы член данных не мог вписаться в void*, поскольку
указатель на элемент данных действительно должен содержать только
смещение. Грубо говоря, указатель на член данных будет
никогда не должен быть больше чем size_tи void* должно быть
по крайней мере, такой же большой, как size_t, С другой стороны, это может
легко содержать битовые шаблоны, которые не были допустимы в указателе.

На самом деле, как отмечает Стив Джессоп, указатели на член требуют дополнительной информации, поскольку, если член находится в виртуальной базе, его смещение зависит от самого производного класса и должно вычисляться динамически на основе дополнительной информации в указателе.

В целом, void* может содержать только указатель на данные.
Он должен быть таким же большим, как самый большой указатель данных (обычно
char*), но указатели на функции и указатели на элементы могут
быть больше и не соответствовать (и указатель на функции-члены почти
никогда не подходит).

2

Вы пытаетесь сделать что-то подобное?

struct ABC
{
int a;
int b;
char c;
};

int main()
{
ABC abc;
char *ptt1 = &abc.c;
void *another_ptr = (void*)ptt1;
}
0
По вопросам рекламы [email protected]