2010-11-22 7 views
0

In einer Anwendung, die ich wartend, stieß ich auf eine Persistenzklasse, die 6 Funktionen hatte, die alle das gleiche taten, außer für den Typ des Elements, das beibehalten wurde. Diese Elemente sind alle von derselben Basisklasse - ein Kandidat für eine Template-Funktion.Templated Funktion erstellt scheinbar temporäre Container

Aber sobald ich sie umgewandelt hatte, würde es scheinen, wenn die Funktion in den Container getreten wird, in den geschrieben wird, ist immer leer (eine temporäre Kopie wird erstellt?) Trotz der Tatsache, dass es mehrere Elemente darin haben sollte . Um den Container im Debugger zu überprüfen, hat er null Items. Auch die Schreibfunktion löst ein Ereignis aus, das den Client über eine Statusänderung informiert, aber wenn dieser Thread das Element aus der Deque extrahiert, ist es immer leer.

Die Basisklasse heißt CItem und alle anderen Artikel sind Spezialitäten dieses Artikels (, usw.). Sie sind alle in einer Deque (std::deque<std::tr1::shared_ptr<CItem>> m_items;) und auf der Festplatte gespeichert. Die Elemente werden korrekt auf den Datenträger geschrieben. Nach der korrekten Verarbeitung werden die Objekte sowohl von der Festplatte als auch von der Festplatte entfernt.

Einzelteile werden mit dem Code m_persistence.Add<CErrorItem>(errorItem); hinzugefügt

Alle Daten für Elemente gespeichert sind, in einfachen Strukturen (zB ErrorItemInfo) und die Einzelteile nehmen Sie diese einfachen Datenspeicher in ihren Konstruktor. Es ist diese Struktur, die im folgenden Code durch die U bezeichnet wird. Die T ist die abgeleitete CItem.

Die Funktion, die die Elemente hinzufügt, ist die folgende:

template <typename T, typename U> 
    std::tr1::shared_ptr<T> CPersistenceManager::Add(const U& item) 
{ 
    std::tr1::shared_ptr<T> newItem = std::tr1::shared_ptr<T>(new T(item)); 
    // .. a couple of lines calling helper functions to generated a unique timestamped filename 
    newItem->Write(filename); // this writes to disk and works. 
    m_items.push_back(newItem); // m_items is always empty 
    SetEvent(m_itemAddedEvent); // notify the client an item has been added. 
    return newItem; 
} 

Die einfachste Lösung ist, den Code wieder auf bestimmte Funktionen zurückzukehren, und wahrscheinlich werde ich das tun, aber ich möchte verstehen, warum das so ist So kann ich es in Zukunft vermeiden.

+1

Ich glaube nicht, dass das, was Sie geschrieben haben, genug ist, um zu sehen, was genau los ist –

+0

Lassen Sie mich wissen, was zu erweitern und ich werde erarbeiten. –

+0

Es wäre interessant, die 'size()' der Deque vor und kurz nach 'push_back' zu kennen. –

Antwort

0
shared_ptr<T> is a potentially different type to shared_ptr<CItem> 

Könnte es sein, dass Ihre gesamte Persistenzklasse für jedes T spezialisiert wird?

+0

Ich hatte das nicht berücksichtigt - ich dachte, es könnte eine Kopie der Deque erstellen. Wie kann das passieren? –

+0

Es ist schwer ohne den Rest des Codes zu sagen - könnte ein spezifisches Implementierungsproblem sein, wo der T-Parameter tatsächlich eine ganz andere Instantiierung von CPersistenceManager oder zumindest von m_items auslöst. Eine andere Möglichkeit ist, dass die Konvertierung von shared_ptr nach shared_ptr immer fehlschlägt, so dass m_items immer leer bleibt –

Verwandte Themen