Преобразовать указатель, который указывает на известный член неизвестного экземпляра (но известного класса) в экземпляр-владелец - PullRequest
1 голос
/ 20 сентября 2019

Учитывая указатель, который указывает на известный член объекта, как я могу получить указатель на вмещающий объект?

Есть ли лучший способ, чем следующий?Это даже верно?

struct data {
    int a,b;
};

data dummy;
static const std::ptrdiff_t offs_a = reinterpret_cast<char*>(dummy.a) - reinterpret_cast<char*>(dummy);
void main(){
    data d;
    int *v = &(d.a);
    data *owner = reinterpret_cast<data *>(reinterpret_cast<char*>(v) - offs_a);
    owner->b = 1;
}

В частности, мне не нравится использование фиктивного объекта dummy только для определения смещения указателя.Есть ли способ прямого приведения, возможно, с использованием указателя на член, чтобы указать, какой (известный) член v указывает на?

1 Ответ

3 голосов
/ 20 сентября 2019

Вы можете использовать макрос offsetof.

Цитирование cppreference :

Макрос offsetof расширяется до целочисленного константного выражения типа std::size_t, значение которого является смещением в байтах от начала объекта указанного типа к указанному ему члену, включая заполнение, если оно есть.

Гарантированно будет работать только для стандартные типы макетов , но для вашего случая все должно быть в порядке.

РЕДАКТИРОВАТЬ: Исходный код может быть написан так:

data d;
int *v = &(d.a);
data *owner = reinterpret_cast<data *>(reinterpret_cast<char *>(v) - offsetof(data, a));
owner->b = 1;
...