2017-03-11 6 views
1

Lassen Sie uns sagen, dass es eine Klasse ist:Können Konstruktoren erstellt werden, die den Verweis auf die alten Elemente basierend auf Parametern zurückgeben?

class X { 
    public: 
     static X& get_instance(int foo, int bar); 
    private: 
     X(); 
     int foo, bar; 
} 

Wenn ich das richtig schrieb dann get_instance einen benannten Konstruktor ist. Nun, hier ist, was ich versuche zu tun;

Lassen Sie uns eine Instanz von X erstellen;

X& first = X::get_instance(3, 5); 
X& second = X::get_instance(4, 6); 
X& third = X::get_instance(3, 5); 

mag ich get_instance so schreiben, dass, wenn es mit den gleichen Parametern zweimal aufgerufen wird, anstatt eine neue Instanz zu schaffen, es sollte nur einen Verweis auf den alten zurück. Wenn die Instanzen, die mit Parametern (3, 5) erstellt wurden, alle gelöscht werden, erstellen Sie eine neue Instanz mit (3, 5).

Ich stellte mir vor, dass dies möglich wäre, indem man den Operator für die Gleichheitsprüfung überlädt und jedes Objekt verfolgt, das der Konstruktor bisher erstellt hat. Aber das ist C++, und es muss einen besseren Weg geben, es zu tun.

+1

Was meinen Sie mit "gelöscht"? – melpomene

+0

Das klingt wie das "Fliegengewicht-Muster". Wenn ja, schau dir [Boost-Fliegengewicht] an (http://www.boost.org/doc/libs/1_63_0/libs/flyweight/doc/index.html) – PaulMcKenzie

+0

Speichere eine 'map' von Argumenten an X's –

Antwort

1

Herb Sutter's favorite 10-liner, für etwas andere Argumente angepasst und Entfernen der Sperre:

static std::shared_ptr<X> X::get_instance(int foo, int bar) { 
    static std::map<std::pair<int, int>, std::weak_ptr<X>> cache; 

    auto key = std::make_pair(foo, bar);  
    auto sp = cache[key].lock(); 
    if (!sp) cache[key] = sp = std::shared_ptr<X>(new X(foo, bar)); 
    return sp; 
} 

nicht make_shared da der Konstruktor privat nutzen kann, ist, es sei denn, Sie einer der Tricks auf this question vorgeschlagen verwenden.

Verwandte Themen