Frage

Ich arbeite in einer eingebetteten Umgebung (Arduino / AVR ATMega328) und will die Factory Method Muster in C ++ implementieren. Allerdings ist der Compiler I (avr-gcc) bin nicht mit dem new Stichwort unterstützen. Gibt es eine Möglichkeit, dieses Muster zu implementieren, ohne new mit?

War es hilfreich?

Lösung

Da der AVR-Compiler auf dem gcc-Compiler basiert, ist es sehr wahrscheinlich, das neue Schlüsselwort zu unterstützen. Was genau ist der Fehler Sie bekommen. Ich vermute, es ist ein Link / Compiler-Fehler entlang der Linien von einer undefinierten Funktion, nämlich Operator neu. Es gibt einen Unterschied zwischen dem neuen Betreiber und Betreiber neu, wird das erste verwendet, um Objekte zu erstellen und diese verwendet wird, um Objekte Speicher zuzuweisen. Der neue Betreiber ruft Betreiber neu für die Art des Objekts erstellt wird, dann ist das V-Tabelle des Objekts initialisiert und ruft die Konstrukteure des Objekts. Lesen der FAQ es sagt, dass Betreiber neu definiert wird nicht in die Standardbibliotheken. Dies ist einfach zu beheben, nur eine definieren:

void *operator new (size_t size)
{
  return some allocated memory big enough to hold size bytes
}

und Sie benötigen, um eine wie auch definieren löschen:

void operator delete (void *memory)
{
   free the memory
}

Das einzige, was hinzuzufügen ist die Speicherverwaltung, die Zuteilung und Freigabe von Speicherblöcken. Dies kann trivialerweise getan werden, wobei darauf geachtet, keine bestehenden zugewiesenen Speicher zu verprügeln (den Code, statischen / globalen Daten, der Stapel). Sie sollten zwei Symbole definiert haben - eine für den Beginn des freien Speichers und eines für das Ende des freien Speichers. Sie können dynamisch zuweisen und in diesem Bereich eines beliebigen Teil des Speichers freizugeben. Sie müssen diese Speicher selbst verwalten.

Andere Tipps

Wenn es keine Möglichkeit gibt, eine Klasse zur Laufzeit zu instanziiert, ich nehme an, dies ist nicht möglich. Alles, was Sie tun können, ist einige Objekte bei der Kompilierung im Voraus zuweisen, erstellen Sie Verweise auf sie und sie zurück, wenn nötig.

Das große Bild der Factory-Methode ist die Objekterstellung, die Heap-Speicherverbrauch bedeutet. Auf einem Embedded-System, werden Sie von RAM beschränkt und müssen alle Ihre Design-Entscheidungen mit Ihren Speichergrenzen im Auge zu machen. Der ATmega328 hat nur 2 KB RAM. Ich würde empfehlen, gegen in einem so engen Raum dynamisch zugewiesenen Speicher.

Ohne Ihr Problem genauer zu wissen, würde ich empfehlen, statisch eine Handvoll von Instanzen der Klasse deklarieren und diese Instanzen in irgendeiner Art und Weise wiederverwenden. Das heißt, Sie müssen wissen, wann und warum Sie Ihre Objekte erstellt werden und - genauso wichtig - wann und warum sie am Ende; dann müssen Sie herausfinden, wie viele Sie gleichzeitig aktiv haben müssen und wie viele es möglich ist, zu einer Zeit aktiv zu haben.

!! Dean

Was ist so etwas wie das?

MyClass *objp = (MyClass*)malloc(sizeof(MyClass));
*objp = MyClass();  // or any other c'tor

EDIT:. Vergessen zu erwähnen, nimmt MyClass einen Zuweisungsoperator hat

EDIT2: Eine andere Sache, die ich vergessen - ja, es gibt eine Gotcha (es ist C ++ gibt es immer gotchas). Sie werden das d'tor manuell für das Objekt haben zu nennen, da Sie nicht kostenlos nutzen können.

Wenn Sie Fabrik verwenden bedeutet, dass Sie einige dynamische Bindungsverhalten wollen, das anzeigt, dass Sie einige virtuelle Funktionen haben. Obwohl, kann es möglich sein, den Speicher für das Objekt unter Verwendung von malloc zuzuweisen () die VTable der Klasse nicht richtig eingerichtet werden und damit der Aufruf von virtuellen Funktionen abstürzen. Ich sehe keine Möglichkeit, dies zu tun, wenn die dynamische Bindung erforderlich ist.

Können Sie malloc tun? Wenn ja Sie Ihr Objekt auf diese Weise malloc können.

Auch was ist die Natur der Objekte, die Sie aus der Fabrik erstellen?

  • Sind sie imutable?
  • Ist die Fabrik nur dazu gedacht eine begrenzte Menge von Objekten zu erzeugen, die zum Zeitpunkt der Kompilierung bekannt sein können?

Wenn die Antwort ja auf beiden Fragen, können Sie statisch den Speicher für Ihre Gruppe von unveränderlichen Objekten zuweisen und die Factory-Methode Rückkehr Zeiger auf das entsprechende Objekt lassen.

Das wird nicht funktionieren, wenn die Antwort nicht auf beiden Fragen ist. Wuth diesen Ansatz auch Sie das Problem der immer mit, dass der Speicher zugewiesen.

Eine Art, wie ich dieses Problem in einem eingebetteten System mit strengen Kodierungsstandards gelöst habe (wo wir waren nicht erlaubt „neu“ oder „Löschen“ zu verwenden) war ein statisches Array des gewünschten Objekts zu erstellen. Und dann verwendet statische Zeiger auf die bereits zugewiesenen Objekte, die zurückgegebenen Werte zu speichern (unter Verwendung von statischen Variablen und / oder Elementvariablen) für die spätere Ausführung der verschiedenen Objekte.

// Class File ---------------------------------------------------
class MyObject {
    public:
        MyObject* getObject();

    private:
        const int MAX_POSSIBLE_COUNT_OF_OBJECTS = 10;
        static MyObject allocatedObjects[MAX_POSSIBLE_COUNT_OF_OBJECTS];

        static allocatedObjectIndex = 0;
};

// Implementation File ------------------------------------------

// Instantiate a static array of your objects.
static MyObject::allocatedObject[MAX_POSSIBLE_COUNT_OF_OBJECTS];

// Your method to return already created objects.
MyObject* MyObject::getObject() {

    if (allocatedObjectIndex < (MAX_POSSIBLE_COUNT_OF_OBJECTS - 1)) {
        return allocatedObjects[allocatedObjectIndex++];
    } else {
        // Log error if possible
        return NULL;
    }
}

Bitte seien Sie gewarnt. Das ist alles aus dem Gedächtnis, wie ich habe keine C ++ geschrieben in über 8 Monate.

Auch. Hinweis: Dies hat einen gravierenden Nachteil, dass Sie eine Reihe von RAM bei der Kompilierung werden die Zuweisung

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top