Ich habe das Kapitel in Beautiful Code auf dem Linux-Kernel gelesen und der Autor diskutiert, wie Linux-Kernel die Vererbung in der C-Sprache (neben anderen Themen) implementiert. Kurz gesagt, eine 'Basis'-Struktur wird definiert und um von ihr zu erben, platziert die Struktur' Unterklasse 'eine Kopie der Basis am Ende der Unterklassen-Strukturdefinition. Der Autor verbringt dann ein paar Seiten mit der Erläuterung eines cleveren und komplizierten Makros, um herauszufinden, wie viele Bytes zurück zu übertragen sind, um vom Basisteil des Objekts in den Unterklasse-Teil des Objekts zu konvertieren.Linux Kernel: Warum setzen 'Subklassen' Strukturen am Ende Basisklasseninformationen?
Meine Frage: Innerhalb der Unterklasse Struktur, warum nicht erklären die Basis-Struktur als erste Sache in der Struktur, anstelle der letzten Sache?
Der Hauptvorteil der ersten Base Struct Stuff ist, wenn Sie von der Basis auf die Unterklasse umwandeln, müssen Sie den Zeiger überhaupt nicht bewegen - im Wesentlichen bedeutet die Cast nur dem Compiler, den Code verwenden zu lassen die 'zusätzlichen' Felder, die die Unterklassenstruktur nach dem von der Basis definierten Inhalt platziert hat.
Nur meine Frage ein wenig lassen Sie mich einige Code werfen, um zu klären, aus:
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?
}
Wenn man innerhalb eines usb_device Objekt einen Zeiger auf das „dev“ Feld haben geschieht dann, um es zu werfen Zurück zu diesem usb_device-Objekt muss man 8 von diesem Zeiger subtrahieren. Aber wenn "dev" das erste Ding in einem usb_device-Casting wäre, müsste der Zeiger den Zeiger überhaupt nicht bewegen.
Jede Hilfe zu diesem würde sehr geschätzt werden. Selbst Ratschläge, wo man eine Antwort finden könnte, wären willkommen - ich bin mir nicht sicher, wie Google den architektonischen Grund für eine solche Entscheidung nennen soll. Die nächstgelegene ich hier auf Stackoverflow finden könnte, ist: why to use these weird nesting structure
Und nur klar zu sein - Ich verstehe, dass viele hellen Menschen auf dem Linux-Kernel für eine lange Zeit gearbeitet hat, so klar es gibt einen guten Grund, es zu tun Auf diese Weise kann ich einfach nicht herausfinden, was es ist.
Das sieht mehr wie Komposition als Vererbung für mich. Gibt es im Linux-Kernel wirklich Code, der "struct device" herunterlädt? – nwellnhof
Im Linux-Kernel gibt es kein Problem, es vor, nach oder in der Mitte zu setzen. Dieser spezifische Auszug ist ein Beispiel für Stil. Der reale Benutzer ruft in jedem Fall container_of_makro auf, um eine Unterklasse von einer Basisklasse zu erhalten. Also, struct usb_device * ud = container_of (p, struct device, dev); ', wobei p ein Zeiger auf das Objekt struct device ist. – 0andriy
Rate: Nun, ein Cast auf einen Wert (kein Pointer) würde etwas ähnliches wie das Slicen machen, was es dir erlauben würde, es als 'Gerät' zu benutzen. Dies wäre nicht der Fall, wenn es zuerst platziert würde. –