Zum Beispiel sind Schwert und Axt zwei verschiedene Klassen, die beide von Waffen erben. Waffe und Trank sind ebenfalls verschiedene Klassen, die beide von Gegenständen erben.
Ich würde die Dinge nicht so machen; Ein Schwert und eine Axt unterscheiden sich hauptsächlich in ihren Daten, nicht in ihrem grundlegenden Verhalten als Waffen. Ebenso bei Gegenständen. Ich würde diese übermäßige Verwendung von Vererbung vermeiden, indem ich mich zunächst auf nur Weapon
und beschränke Item
(Sie könnten diese sogar zu einer einzigen Klasse zusammenfassen, aber das ist eine andere Diskussion). Wenn nichts anderes, wird dies die Konstruktorexplosion lindern, in der Sie sehen ItemWrapper
.
Es muss sich also um einen Container mit (intelligenten) Zeigern handeln. Da ich meinen Code nicht mit Aufrufen von new und delete lesen möchte, verpacke ich ihn in eine ItemWrapper-Klasse, die auf ctor / dtor Nachrichten / Löschungen enthält.
Betrachten Sie die intelligenten Boost- Zeiger, anstatt Ihre eigenen zu rollen. Sie sind ziemlich isoliert vom Rest von Boost (so dass Sie nicht viele Abhängigkeiten haben, wenn Sie aus irgendeinem Grund den Rest von Boosts ordentlichem Zeug nicht ausnutzen möchten) und viele von ihnen Sie wurden als Teil der neuen Standardbibliothek in C ++ 11 übernommen, sodass Sie keine Probleme beim Upgrade haben sollten.
Dies ist mein erster Versuch, also würde ich gerne wissen: gehe ich den richtigen Weg? oder ob es einen besseren Weg gibt (vielleicht einen, der so viele Konstruktoren vermeidet)?
Wie oben würde ich mich bemühen, eine Vererbung zu vermeiden und etablierte Lösungen von Drittanbietern zu verwenden, anstatt Ihre eigenen zu rollen. Diese Schritte allein sollten einen Großteil der Wartungskomplexität beseitigen, die Sie entdecken (oder in Kürze entdecken werden).
Ein anderer Ansatz besteht darin, es so zu betrachten: Es ItemWrapper
ist ein Pflaster für ein Implementierungsdetailproblem. Es selbst repräsentiert kein reales "Objekt" im typischen Sinne. Überlegen Sie sich also, was eine bessere Analogie sein könnte, die auch Ihr Problem löst, einen Platz für die Automatik new
und delete
Anrufe zu haben.
In den meisten Lagerbeständen können (einige) Gegenstände gestapelt werden, nicht wahr?
Die "Stapelbarkeit" eines Elements ist eine Eigenschaft dieses Elements, aber das Element selbst sollte nicht für die Wartung des Stapels verantwortlich sein. Wenn Sie eine Klasse haben, die eine ItemStack
mit Methoden zum Abfragen der Größe des Stapels, zum Teilen des Stapels usw. darstellt, können Sie die Lebensdauer des Elementzeigers verwalten (was, wie ich beachten sollte, bei Stapeln etwas komplizierter werden kann Dies liefert ein weiteres Argument für die Verwendung von Boost in der Stack-Klasse zusammen mit der Implementierung des restlichen Verhaltens. Elemente, die nicht gestapelt werden können, werden durch einen Stapel dargestellt, der immer einen einzelnen Artikel enthält, und Ihr Inventar selbst behandelt immer noch homogene Instanzen von ItemStack
.