Я читал главу в Beautiful Code на ядре Linux, и автор обсуждает, как ядро Linux реализует наследование на языке C (среди других тем). В двух словах определена «базовая» структура и для того, чтобы наследовать от нее, структура «подкласса» помещает копию базы в конце определения структуры подкласса. Затем автор проводит пару страниц, объясняя умный и сложный макрос, чтобы выяснить, сколько байтов назад, чтобы преобразовать из базовой части объекта в часть подкласса объекта.Ядро Linux: почему структуры «подкласса» помещают информацию базового класса в конец?
Мой вопрос: В подклассе структуры, то почему бы не объявить базовую-структуру как первой вещи в структурах, вместо последней вещи?
Главное преимущество кладки базового элемента структуры в первую очередь заключается в том, что при отливке от базы к подклассу вам вообще не нужно будет перемещать указатель - по существу, делая приведение просто означает, что компилятор должен использовать ваш код «дополнительные» поля, которые структура подкласса помещала после материала, определяемого базой.
Просто чтобы прояснить мой вопрос немного дайте мне пролить некоторый код из:
struct device { // this is the 'base class' struct
int a;
int b;
//etc
}
struct usb_device { // this is the 'subclass' struct
int usb_a;
int usb_b;
struct device dev; // This is what confuses me -
// why put this here, rather than before usb_a?
}
Если случается иметь указатель на поле «Dev» внутри объекта usb_device то для того, чтобы бросить его назад к этому объекту usb_device нужно вычесть 8 из этого указателя. Но если «dev» было первым делом в использовании usb_device, то указателю вообще не нужно было бы перемещать указатель.
Любая помощь в этом была бы принята с благодарностью. Даже совет о том, где найти ответ, будет оценен по достоинству - я не совсем уверен, как Google за архитектурную причину такого решения. Ближайший я мог бы найти здесь, на StackOverflow является: why to use these weird nesting structure
И, просто чтобы быть ясно, - я понимаю, что много ярких людей работали на ядре Linux в течение длительного времени, так ясно, что есть веская причина сделать это таким образом, я просто не могу понять, что это такое.
Это больше похоже на композицию, чем наследование для меня. Действительно ли код в ядре Linux опускает «struct device»? – nwellnhof
В ядре Linux нет никаких проблем, чтобы поставить его до, после или в середине. Эта конкретная выдержка является образцом стиля. Настоящий пользователь в любом случае вызывает container_of macro, чтобы получить подкласс из базового класса. Таким образом, 'struct usb_device * ud = container_of (p, struct device, dev);', где p является указателем на объект struct device. – 0andriy
Угадайте: ну, отличное от значения (не указатель) могло бы выполнить что-то похожее на нарезку, возможно, это позволит вам использовать его как «устройство». Это было бы не так, если бы оно было помещено первым. –