Hallo Newby,
ich habe deinen Framework jetzt ein bisschen genauer angeschaut und gebe jetzt ein wenig meinen Senf dazu und auch ein paar Tipps.
Habe da schon ein wenig Erfahrung bei größeren Projekten ( unter anderem Sacred 2 ) und werde dich erstmal auf grobe Fehler hinweisen.
a) Ein Wort "declar
etions" (declaretions.h) gibts nicht, es heisst Declar
ations.
b) du includierst zwar alle deine Klassen Header nur in der Simple2D.h und niergendwo sonst. Aber gewöhn dir trotzdem bei jedem Header Include-Guards zu schreiben, sonst hast du später große Probleme.
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
|
#ifndef HEADERNAME_H
#define HEADERNAME_H
#ifdef (_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
// dein code hier
#endif
|
Kurze Erklärung dazu:
Normalerweise würden nur "pragma once" oder Include-Gurads reichen, aber wenn du sicheren und portablen Code schreiben willst, benutz beides. Pragma once läuft beim Kompilieren viel schneller (
Link MSDN : "This can reduce build times as the compiler will not open and read the file after the first #include of the module.") Aber läuft nicht mit allen Compilern. Bei dem Codegerüst oben wird also pragma once genommen, wenn man deinen Framework mit Visual Studio kompiliert, wenn nicht, werden langsamere aber mit allen Compilern laufende Include-Guards genommen.
c) Bei deinen Exceptions nutzt du immer 2 Parameter (Errorcode und einen Beschreibun-String). Wenn du mit Errorcodes arbeiten willst, dann übergib als Parametern nur die und keine Strings. Dann sparst du dir bei gleichen Errornummern an verschiedenen Stellen die Tipparbeit und minimierst Vertipp-Gefahr. In der Exceptionklasse kannst du dir einfach eine Methode machen, z.B. std::wstring GetErrorDescription(int Number), die dir diese Beschreibung liefert.
d) Du wirfst überall Exceptions (ist gut), fängst die aber niergendwo. Bei manchen Stellen musst du das machen, z.B. da wo du in deinen Methoden andere deine Methoden aufrufst. Genauso musst du auch diese Exceptions dann verarbeiten, um z.B. deinen Code backrollen / aufräumen oder Exceptions weiterleiten.
e) Was davor bespochen wurde mit Create und Destroy und wie du das jetzt umgebaut hast, halte ich für falsch. Ich würde die Methoden beibehalten und das nicht im Konstruktor/Destruktor direkt machen.
Sondern würde dann, da wo es sein muss mehrere default Constructors machen:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class RenderDevice
{
RenderDevice();
RenderDevice(int width, int height);
Create(int width, int height);
Destroy();
};
RenderDevice::RenderDevice()
{
}
RenderDevice::RenderDevice(int width, int height);
{
Create(width, height);
}
RenderDevice::~RenderDevice()
{
Destroy();
}
|
Somit gibst du dem Benutzer freie Wahl, ob der direkt beim Erstellen der Instanz die Initialisierung vornehmen will oder danach. Genau das gleiche für Destruktor, somit kann der Benutzer die Aufräumarbeiten vor der Zerstörung der Instanz vornehmen (ist auch nötig, weil z.B. explizites Aufrufen vom Destruktor nicht geht, z.B. bei einer Exception).
f) Bei deinen Klassen hast du einige private Members, was ok ist, aber die musst du alle im Konstruktor erstmal initialisieren. Alle Zeiger auf 0, alle Strukturen mit memset leeren, alle stl Container am besten mit clear() reseten.
Wenn du manche Zeiger uninitialisiert benutzst, dann zeigen die auf 0xcdcdcd (Nirvana), wird es recht heftig crashen. Manchmal auch nur in Release Version, so dass du es gar nicht bei der Entwicklung merkst und die Fehlersuche stark erschwert wird.
g) Benutze keine chars* oder wchars*, benutze std::string und std::wstring.
h) Benutze keine rohe Zeiger, benutze std::tr1::shared_ptr / std::tr1::scope_ptr (oder alternativen aus Boost).
Ein wenig zur Optimierung und Verbesserung:
i) Pack deinen Framework in ein Namespace, so vermeidest du Kollisionen und Namenskonflikte mit anderen Bibliotheken.
j) Benutze da wo es möglich ist nicht i++, sondern ++i, z.B. in deinen for Schleifen. Die Compiler optimieren da den Code besser.
k) Declariere deine eigene Datentypen, z.B. typedef unsigned int u32, damit kannst du deinen Code später portieren und kapseln.
Ok, bevor ich hier alle Buchstaben aufbrauche, kannst du vielleicht diese Sachen verbessern (oder Gegenteil argumentieren).
Viele Grüße,
Sergius