Указатели на представления членов

Я пытаюсь сделать несколько обратных вызовов из функций-членов, и все было в порядке, пока я не попытался использовать класс шаблона, производный от 2 классов, в качестве объекта обратного вызова, когда я получил следующую ошибку:

error C2440: 'reinterpret_cast' : Pointers to members have different representations; cannot cast between them

Эта вещь сигнализировала мне, что указатели на функции-члены имеют разные представления (дох!)

Каковы эти представления? В чем разница между ними?

10

Решение

Дэнни Калев объясняет это довольно хорошо:

Базовое представление указателей на членов

Хотя указатели на участников ведут себя как обычные указатели, за кулисами их представление совершенно иное. Фактически, указатель на член обычно состоит из структуры, содержащей в некоторых случаях до четырех полей. Это связано с тем, что указатели на члены должны поддерживать не только обычные функции-члены, но и виртуальные функции-члены, функции-члены объектов, которые имеют несколько базовых классов, и функции-члены виртуальных базовых классов. Таким образом, простейшая функция-член может быть представлена ​​в виде набора из двух указателей: один содержит адрес физической памяти функции-члена, а второй — содержит this указатель. Однако в таких случаях, как функция виртуального члена, множественное наследование и виртуальное наследование, указатель на член должен хранить дополнительную информацию. Следовательно, вы не можете приводить указатели на элементы к обычным указателям, а также не можете безопасно разыгрывать указатели на элементы различных типов.

Чтобы получить представление о том, как ваш компилятор представляет указатели на члены, используйте sizeof оператор. В следующем примере взяты размеры указателя на элемент данных и указателя на функцию-член. Как видите, они имеют разные размеры, следовательно, разные представления:

struct A
{
int x;
void f();
};
int A::*pmi = &A::x;
void (A::*pmf)() = &A::f;
int n = sizeof (pmi); // 8 byte with my compiler
int m = sizeof (pmf); // 12 bytes with my compiler

Обратите внимание, что каждый из этих указателей может иметь различное представление, в зависимости от рассматриваемого класса и от того, является ли функция-член виртуальной.

16

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

Это вещь Microsoft: в некоторых случаях они делают указатели на функции-члены меньшими, за счет создания указателей на функции-члены, которые имеют разные представления, как вы только что видели. Где-то есть переключатель, чтобы отключить это, чтобы все указатели на членов имели одинаковое представление.

2

По вопросам рекламы [email protected]