2016-11-09 3 views
0

Ich schreibe Code für eine eingebettete Plattform, daher kann ich den normalen neuen Operator nicht verwenden.C++, Hinzufügen von temporären Objekten zu einer Liste ohne dynamische Speicherzuweisung

Jetzt möchte ich beliebige Objekte zu einer Liste hinzufügen, genau so.

tp.add(DerivedA("David")); 
tp.add(DerivedB("Max")); 
tp.add(DerivedC("Thomas")); 

Aus dem Grunde der Code-Duplizierung Ich mag nicht, so etwas schreiben:

tp.add(new (myalloc(sizeof(DerivedB))) DerivedB("John")); 
// using placement-new works 

: würde

DerivedA david("David"); 
tp.add(david); 
... 

Eine Lösung, aber nicht sehr hübsch Stil dies sein Jetzt habe ich versucht, ein temporäres Objekt hinzuzufügen, das mit dem Zeiger übergeben wurde:

tp.add(&DerivedA("David")); 

Theoretisch könnte das funktionieren, aber der Compiler beklagt sich (aus gutem Grund) darüber, einen Zeiger auf ein temporäres Objekt zu geben (-fmissiv).

Gibt es eine saubere Art zu tun, was ich will? Hier

ist ein vollständiges Beispiel:

#include <iostream> 

using namespace std; 

class Base // base class 
{ 
public: 
    Base(); 
    int size; 
    char name[100]; 
}; 

class Derived:public Base 
{ 
public: 
    Derived(char* name); 
}; 

class ThirdParty 
{ 
public: 
    void add(Base* obj); 
    void addTemp(Base* tempObj); 
    Base* list[10]; 
    int index; 
}; 


void* myalloc(int size){ 
    void* p; 
    // ... 
    // allocate memory in a static memory pool 
    // ... 
    return p; 
} 

void memcpy(void* to, void* from, int size){ 

} 


int main() 
{ 
    ThirdParty tp; 

    // The ugly style: 
    tp.add(new (myalloc(sizeof(Derived))) Derived("John")); // using placement-new works 

    // The beauty style (compiler complains here): 
    tp.addTemp(&Derived("David")); // create temporary object here, which is copied and added to the list 
    tp.addTemp(&Derived("Max")); 
    tp.addTemp(&Derived("Thomas")); 

    return 0; 
} 


Base::Base() 
{ 
    size = sizeof(Base); 
} 

Derived::Derived(char *name) 
{ 
    size = sizeof(Derived); // make size of this object available for a base-pointer 
} 

void ThirdParty::add(Base *obj) 
{ 
    list[index++] = obj; 
} 

void ThirdParty::addTemp(Base* tempObj) 
{ 
    Base* newObj = (Base*) myalloc(tempObj->size); // let third party allocate memory 
    memcpy(newObj, tempObj, tempObj->size); // copy the temporary object 
    list[index++] = newObj; 
} 
+0

ein bisschen schöner könnte dieses Makro sein: "#define m (x) neu (myalloc (sizeof (x))) x" –

Antwort

0

Meine bevorzugte Lösung ist nun das folgende Makro:

#define m(x) new (myalloc(sizeof(x))) x 

jetzt kann ich ein neues Objekt mit diesem Code hinzu:

tp.add(m(Derived("Isabella"))); 
0

Wenn Sie C++ 11, können Sie eine Weiterleitungsfunktion schreiben für Sie die Arbeit zu tun:

template <typename T, typename... Args> 
T* make (Args&&... args) { 
    return new (myalloc(sizeof(T))) T { std::forward<Args>(args)... }; 
} 

Sie würden dann hinzufügen ein Objekt in der Liste wie folgt:

tp.add(make<Derived>("John")); 
+0

danke, scheint eine mögliche Lösung zu sein. Aber ich denke Autovervollständigung funktioniert dann nicht mehr für den Konstruktor ?! –

+0

Ich habe gerade Ihren Ansatz getestet, und die Code-Vervollständigung (Vorschläge) funktioniert nicht mehr wie erwartet mit QtCreator. –

+0

Ich denke, das Verlieren von Code-Vervollständigung ist Macro-Hacks weit vorzuziehen, aber vielleicht bin ich es nur. – TartanLlama

0

Können Sie nicht nur neue überschreiben myalloc zu benutzen? Wenn Sie dies nicht global tun möchten, können Sie es sicherlich für Base

Verwandte Themen