Наследование от дескрипторов libuv

Дескрипторы libuv имеют поле void* data для переноса любой контекстной информации (довольно стандартный шаблон для обратных вызовов в C-land). Однако, поскольку я работаю в C++-стране, я хотел бы использовать наследование для непосредственного хранения контекста в дескрипторе. Основное преимущество заключается в хранении нескольких элементов контекста, для которых IIUC требует выделения кучи для объединения их в один указатель, скажем, std::tuple<...>* или какую-то временную структуру (поправьте меня, если я ошибаюсь, и я могу избежать выделения кучи даже в C-land) .

Мои основные опасения:

  1. Указатели на дескрипторы в конечном итоге используются в C-land (библиотека libuv). Не уверен, что здесь есть какие-либо угловые случаи, связанные с взаимодействием.
  2. libuv имеет собственную систему псевдонаследования путем повторения полей от родителей в дочерних элементах. Это похоже на то, как компилятор может размещать поля из базовых классов в производных классах. Не уверен, как это будет взаимодействовать с наследованием С++.
  3. Из того, что я исследовал, стандарт на самом деле не определяет какой-либо макет памяти для наследования, это зависит от компилятора. Не уверен, что это влияет на вещи.

Итак, могу ли я безопасно наследовать от дескрипторов libuv в C++? Бонусные баллы, если вы также можете прояснить вышеуказанные моменты.


person Roshan    schedule 23.07.2020    source источник
comment
Выделяет ли libuv дескрипторы или вы выделяете дескрипторы?   -  person user253751    schedule 23.07.2020
comment
Я сам выделяю его с помощью new. Если libuv сделает это (гипотетически), я думаю, наследование не сработает, так как нет доступной памяти для каких-либо полей производного класса.   -  person Roshan    schedule 23.07.2020


Ответы (1)


Если вы сами выделяете дескрипторы, а затем передаете их libuv, ничто не мешает вам их наследовать. Вы можете распределять их как хотите. Вы можете сделать их членами своего класса, но вы также можете сделать их базой своего класса.

Компилятору не разрешено изменять расположение памяти дескриптора libuv только потому, что это базовый класс. Разрешено решать, где находится база в общей структуре класса, но нельзя изменять саму базу. (В противном случае указатели на базовый класс должны были бы работать по-разному, в зависимости от того, выделили ли вы экземпляр базового класса или производного класса!)

Поскольку компилятор не может изменить структуру памяти, все, что делает libuv, не имеет значения. Если он работает с обычными объектами дескрипторов libuv, он все равно будет работать, когда они используются в качестве базового класса.

Примечание. Если наследование от дескриптора libuv по-прежнему вызывает у вас дискомфорт, вы можете выделить дескриптор как члена вашего класса и сохранить указатель на весь класс в поле контекста libuv.

person user253751    schedule 23.07.2020