Beste Ansatz für Struktur-Polymorphismus in C
Schreibe ich eine einfache 2d-Vektor-Objekt. Es müssen x-und y-Komponenten, und die Länge, Kreuz-Produkt, etc. Methoden. Die Sache ist die, ich will haben die Struktur zu haben, die vielen möglichen Typen (char, int, float, double, etc.). Ich Frage mich, was wäre die beste Wahl, design-Weise, um die Interaktion mit dem Objekt? Hier ist, was ich bin derzeit in Erwägung:
1. Haben Sie den Benutzer übergeben, der ein vector-Objekt um spezielle Funktionen, wie:
Vector2Dt_Dot(Vec2Dt* vector1, Vec2Dt* vector2);
wobei 't' der Typ des Vektors. Jedoch, das problem bei diesem Ansatz ist, dass es verbietet verschiedene Arten von Interaktion mit jedem anderen, so dass ich nicht sagen konnte, berechnen Sie das Skalarprodukt a float vector2d und ein Doppel vector2d. Ein zweiter Ansatz, und was ich bin Neigung in Richtung:
2. Haben die Benutzer-pass vector-Objekt(s) als void-Zeiger, zusammen mit Ihrem Typen, wie:
Vector2D_Dot(void* vector1, unsigned vector1_type, void* vector2, unsigned vector2_type);
offensichtlich dieser Ansatz ist kompakter API-Weise und löst auch das problem von oben, aber auf Kosten von ein paar zusätzliche Parameter und geben Sicherheit.
Möglicherweise gibt es andere Lösungen, ich bin mir nicht bewusst, aber diese sind die, die ich derzeit in Betracht ziehen. Was denken Sie, ist der beste Ansatz, um dieses?
- die Frage ist tagged
c
, nichtc++
- Verwenden Sie nicht die
void *
alternative; es gibt zu viele Möglichkeiten, Sie können Fehler machen, die der compiler nicht abfangen (weil jeder Zeigertyp umgewandelt werden können, um einevoid *
in C oder C++). Zu einer Zeit, diese Frage (kurz) hatten einen C++ - tag und für eine längere Zeit zu verwenden, C++ - Referenz-Typ notation. Wenn C++ ist relevant, erwägen Sie, einevector<vector<yourtype> >
. - leffler: Ja, das war mein Fehler. Ich Wechsel zwischen C und C++ oft. Ich würde auf jeden Fall verwenden Sie einen Vektor-ähnliche Oberfläche, wenn es eine option in C.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was Sie tun können, ist die Verwendung von polymorphen Objekten. Definieren Sie die Strukturen, wie diese:
Dann Sie können schreiben Sie Ihre Funktionen zu akzeptieren
Vector2D
Zeiger, untersuchen Ihre jeweiligen Felder und warfen Sie auf den entsprechenden typisierten Variante, um den Zugriff auf die Nutzdaten.Dies ist Polymorphismus codiert von hand. Alles, was Sie brauchen, um sicherzustellen, ist, dass die
type
Feld ist immer auf den korrekten Wert gesetzt (gesetzt einmal, wenn ein Vektor eingegeben wird erstellt).Der Vorteil dieses Ansatzes auf Ihre zweite Idee ist, dass Sie nicht zu Durchlaufen haben, um die Art der Vektoren eine weitere variable, die mit Ihren Vektoren mühsam und fehleranfällig.
Als alternative können Sie festlegen, Ihren
type
Feld mit einem Zeiger auf eine Struktur von Funktionszeigern. Erstellen Sie ein Objekt von dieser Funktion-Zeiger-Struktur pro getippt, Vector-Art, die Sie definieren, und es verwenden, um die lookup-Funktion zu verwenden, mit dem gegebenen Vektor. Dieser Ansatz wäre sehr nahe an dem, was C++ bietet unter der Haube.Können Sie eine variable Argumentliste, dessen Prototyp kodiert wird, zum Beispiel als:
Dieser Stil muss einem angegebenen parameter, in diesem Beispiel
a
gefolgt von einer beliebigen Anzahl von Parameter, deren Datentypen können zur Laufzeit bestimmt werden.Finden Sie die Funktionen und Objekte:
va_list
;va_start
;va_args
; undva_end
für eine vollständige Beschreibung, wie die Prozess-variable argument-Listen.Hoffe, das hilft. Wenn Fragen über
va_list
usw. Fragen Sie bitte nach.Was ich eigentlich ging, war Folgendes:
Erstellte ich eine base Vector2D-Klasse, mit den folgenden layout:
Wie Sie sehen können, dies erlaubt den generischen Vektor-Funktionen aufrufen, diese zu bekommen, die von abgeleiteten Klassen " x-und y-Werte umgewandelt, um Doppel -, die verhindert, dass die generische Funktion von Gedanken über den Unterschied zwischen Größen von Typen wie char und float. Dann jede abgeleitete Klasse: