Ich habe vor kurzem begonnen, an der Entwicklung von in C geschriebenen APIs zu arbeiten. Ich sehe einige Unterprogramme, die 8(Acht) Parameter erwarten, und für mich sieht es hässlich und umständlich aus, 8 Parameter zu übergeben, während ich dieses bestimmte Unterprogramm aufrufe. Ich habe mich gefragt, ob es nicht eine akzeptablere und sauberere Methode geben könnte.
Antworten
Zu viele Anzeigen?Wenn die API mit so vielen Parametern umständlich erscheint, verwenden Sie einen Zeiger auf eine Struktur, um Parameter zu übergeben, die zugehörige in irgendeiner Weise.
Ich werde Ihren Entwurf nicht beurteilen, ohne ihn aus erster Hand gesehen zu haben. Es gibt legitime Funktionen, die zum Beispiel eine große Anzahl von Parametern erfordern:
- Filter mit einer großen Anzahl von Polynomkoeffizienten.
- Farbraumtransformationen mit Subpixelmasken und LUT-Indizes.
- Geometrische Arithmetik für n-dimensionale unregelmäßige Polygone.
Es gibt auch einige sehr schlechte Entwürfe, die zu Prototypen mit großen Parametern führen. Teilen Sie uns mehr Informationen über Ihren Entwurf mit, wenn Sie sachdienlichere Antworten wünschen.
Ein Muster, das von einigen APIs (wie pthreads
) sind "Attributobjekte", die anstelle von einzelnen Argumenten an Funktionen übergeben werden. Bei diesen Attributobjekten handelt es sich um undurchsichtige Strukturen, die mit Funktionen zum Erstellen, Zerstören, Ändern und Abfragen versehen sind. Alles in allem erfordert dies mehr Code als die einfache Übergabe von 10 Argumenten an eine Funktion, aber es ist ein robusterer Ansatz. Manchmal ist ein bisschen zusätzlicher Code, der Ihren Code verständlicher macht, die Mühe wert.
Ein weiteres gutes Beispiel für dieses Muster finden Sie in der pthreads
API. Ich schrieb ein längerer Artikel über die Gestaltung der pthreads
API vor ein paar Monaten, und dies ist einer der Aspekte, die ich darin angesprochen habe.
Es scheint auch interessant zu sein, diese Frage nicht unter dem Gesichtspunkt der Hässlichkeit/Nicht-Hässlichkeit zu betrachten, sondern unter dem Gesichtspunkt der Leistung.
Ich weiß, dass es einige x86-Aufrufkonventionen die Register für die Übergabe der ersten beiden Argumente und Stack für alle anderen Argumente verwenden kann. Ich denke also, dass wenn man diese Art von Aufrufkonvention verwendet und immer einen Zeiger auf eine Struktur verwendet, um Argumente in Situationen zu übergeben, in denen eine Funktion mehr als 2 Parameter benötigt, der Funktionsaufruf insgesamt schneller sein könnte. Auf dem Itanium werden immer Register für die Übergabe von Parametern an eine Funktion verwendet.
Ich denke, es könnte einen Versuch wert sein.
Sie können auch Folgendes tun einige der Parameter in einen Zustand umwandeln . OpenGL-Funktionen haben weniger Parameter, weil Sie Aufrufe wie:
glBindFramebuffer( .. ) ;
glVertexAttribPointer( .. ) ;
glBindTexture( .. ) ;
glBindBuffer( .. ) ;
glBindVertexArray( .. ) ;
// the actual draw call
glDrawArrays( .. ) ;
Alle diese ( glBind*
Typaufrufe) stellen "Zustandsänderungen" dar, die sich alle auf den nächsten Zeichnungsaufruf auswirken werden. Stellen Sie sich einen Zeichenaufruf mit 20 oder mehr Argumenten vor absolut unüberschaubar!
Die alte Windows-C-API zum Zeichnen hatte auch einen Zustand, der in "opaken Zeiger"-Objekten ( HDC
's, HWND
's..). Ein undurchsichtiger Zeiger ist im Grunde C's Art, private Datenelemente zu erstellen, auf die man nicht direkt zugreifen kann. In der Windows-Zeichen-API würden Sie zum Beispiel einen HDC-Opaque-Zeiger über createDC
. Sie können die internen Werte des DC über die SetDC*
Funktionen, zum Beispiel SetDCBrushColor
.
Jetzt, da Sie einen DC mit einer Farbe und allem eingerichtet haben, können Sie die Rectangle
Funktion in den DC zu ziehen. Sie haben eine HDC
als ersten Parameter, der Informationen über die zu verwendende Pinselfarbe usw. enthält. Rectangle
benötigt dann nur 5 Parameter, die hdc
x,y,Breite und Höhe.
- See previous answers
- Weitere Antworten anzeigen