2016-04-11 11 views
0

Angenommen, ich möchte jedem Objekt einer bestimmten neu erstellten Klasse eine eindeutige ID zuweisen, aber nicht denen, die kopiert werden. Ich so etwas wie könnte:Erzwingen std :: Vektor Aufruf eines bestimmten Konstruktors in Abhängigkeit von einer Instanz einer anderen Klasse

int next_id = 0; // ugly global variable 

class Element { 
    int id; 
public: 
    Element(){ 
     this->id = next_id++; 
    } 
    Element(const Element &other){ 
     this->id = other.id; 
    } 
}; 

und es würde mit stl Bibliothek arbeitet, kann ich

vector<Element> list; 

tun, sondern stattdessen eine globale Variable zu haben, muß ich in einem anderen Objekt next_id haben:

class Context { 
    int next_id; 
public: 
    Element *createElement(){ 
     Element *element = new Element(this->next_id++); 
     return element; 
    } 
}; 

class Element { 
    int id; 
public: 
    Element(int id) : id(id) { 
    } 
    Element(const Element &other){ 
     this->id = other.id; 
    } 
}; 

So kann ich es auf diese Weise verwenden:

Element *element = context->createElement(); 

Aber ich kann es nicht mit Vektor verwenden.

Ich möchte std :: vector rufen Sie den Konstruktor des Elements über eine Funktion wie

context->createElement()
, dh etwas abhängig von einem 'Kontext' -Objekt, und rufen Sie die regulären Kopie Konstruktor beim Ändern der Größe.

Gibt es eine Möglichkeit, dies zu tun? Zum Beispiel durch Übergeben einer Funktorinstanz an Vektor oder etwas anderes? ...

EDIT: Um einen Punkt zu verdeutlichen. Ich erwähne die Verwendung einer anderen Context Klasse, weil ich möchte, dass der Benutzer in der Lage ist, eine neue Serie von ID zu erstellen, indem er ein neues Objekt erstellt und später element s zu dieser neuen context hinzufügt. Zum Beispiel wäre ein äquivalentes Problem ein Element der Klasse zu haben, die wie folgt aussieht:

class Element { 
    Context *context; 
public: 
    Element(Context *context) : context(context){ 
    } 
    Element(const Element &other){ 
     this->context = other.context; 
    } 
}; 

und die Suche nach einem Weg, um ein context Objekt vector angeben, wenn es den Konstruktor aufruft.

+2

Behalten Sie Ihr erstes Beispiel und machen 'next_id' ein' statisches' Element von 'Element'. – user657267

Antwort

0

Ich sehe nicht wirklich, warum Sie next_id in einer anderen Klasse haben möchten. Die einfachste Lösung besteht darin, ein next_id statisches Element von Element zu machen.

class Element { 
public: 
    Element(){ 
     this->id = next_id++; 
    } 
    Element(const Element &other){ 
     this->id = other.id; 
    } 
private: 
    int id; 
    static int next_id; 
}; 

int Element::next_id = 0; 

Dies sollte den Trick tun. Du brauchst keinen benutzerdefinierten "Alocator", was ich für Unsinn halte.

Wenn Ihr Ziel mit ID mehrere Klassen mit einer eindeutigen ID zwischen ihnen haben soll, verwenden Sie Vererbung! Element wäre der Vater aller Unterklassen und es würde sich um Ihre völlig eindeutigen IDs kümmern.

+0

Ich denke, mein Beispiel ist irreführend, weil mein Problem nicht wirklich einzigartige IDs haben. Ich möchte, dass der Benutzer eine neue Reihe von IDs beginnen kann, indem er ein neues "Context" -Objekt erstellt. Ich werde die Frage klären. –

0

Die Standardbibliothek erstellt ihr Element effektiv durch Aufruf a.construct(p, args...). Entsprechend können Sie das Element construct() eines benutzerdefinierten Zuordners verwenden, um anzupassen, wie die Ojekte aufgebaut werden. Dieser Ansatz erfordert, dass der benutzerdefinierte Zuordner verwendet wird. Diese Verwendung kann erzwungen werden, indem die Konstruktoren der entsprechenden Klasse private erstellt werden und ein Ansatz für die Konstruktion des benutzerdefinierten Zuordners bereitgestellt wird.

+0

aber der Zuordner ist eine Klasse, ist es möglich, ein Argument an den Zuordner in der Deklaration des Vektors übergeben? –

+0

@OnurCelebi: die C++ 11 Allokatoren sind zustandsbehaftet, d.h.Von dort kann auf den notwendigen Kontext verwiesen werden und der Allokator wird überall übergeben. –

+0

Sie sind während der Lebensdauer des Vektors zustandsbehaftet, aber gibt es eine Möglichkeit, ihnen während der Deklaration des Vektors ein Argument zu übergeben? –

Verwandte Themen