2010-01-17 11 views
5

Piszę jakąś wirtualną bibliotekę systemów plików dla gier wideo w stylu ROFS oprogramowania pośredniczącego CRI (patrz Wikipedia). Moją intencją z biblioteką jest zapewnienie naturalnych środków dostępu do zasobów opracowywanych przeze mnie gier, które przechowują niektóre dane osadzone w pliku wykonywalnym, niektóre na nośnikach, a inne na dysku twardym lokalnego użytkownika (preferencje, zapisywanie plików gier itp.) .Dlaczego std :: istream nie przejmuje własności nad swoim streaguf?

dostęp do takich zasobów powinno być tak proste jak wykonanie połączenia jak

std::auto_ptr<std::istream> defaultConfigIStream(
    fslib.inputStream("self://defaultConfig.ini")); 
std::auto_ptr<std::ostream> defaultConfigOStream(
    fslib.outputStream("localappdata://config.ini")); 

// Copies default configuration to local user's appdata folder 
defaultConfigIStream >> defaultConfigOStream; 

Faktyczny sposób robienia rzeczy jest rzeczywiście inny, z innej warstwy abstrakcji stosowany do tła załadunku, ale to nie jest ważne tutaj.

Co chcę wiedzieć, jak mogę powrócić że auto_ptr<> (lub unique_ptr<>, wybrać) uznając, że std::streambuf<> związane z std::[i/o]stream<> nie są usuwane przez nią, kiedy to zniszczone.

Rozważam, że std::[i/o]stream<> nie przejmuje własności nad przekazanym do niego strebufiem, ponieważ konstruktor nie przedstawia przeniesienia własności semantyki, a odwołanie Apache do STDCXX nie wspomina o przechodzeniu na własność (ani nie wykonuje żadnego stdlib referencje, które znalazłem w Internecie).

Jakie mam alternatywy? Równie dobrze mógłbym zwrócić wspólny wskaźnik i obserwować go, dopóki menedżer FSlib nie zachowa unikalnej kopii współużytkowanego wskaźnika, w takim przypadku zniszczyłby swoją unikalną kopię, jak również streambuf. Jest to praktyczne, biorąc pod uwagę model organizacyjny biblioteki, ale nie jest to zbyt eleganckie ani wydajne.

Próbowałem rzucić okiem na Boost.Iostreams, ale wydaje mi się, że z nim jest jeszcze gorzej, ponieważ same strumienie mają swoje typy Urządzenia silnie związane z ich typem (urządzenie do strumienia musi być zdefiniowane w swoim parametrze szablonu). Wydaje się, że ten problem sprawia, że ​​wykorzystanie Boost.Iostreams jest niewykonalne w mojej bibliotece, ponieważ musi oddzielić konkretną implementację strumieni "źródła/zlewu", aby można było bezproblemowo wykorzystać strumienie do otwarcia pliku znajdującego się wewnątrz samego pliku wykonywalnego, wewnątrz pliku z systemu plików systemu lub wewnątrz pliku typu archiwum, na przykład.

Mógłbym napisać klasę kontenerów, która obsługuje te problemy, ale wolałbym zrobić to bardziej czysto (tj. Wystarczy, że zwrócisz już strumień, to wszystko, czego trzeba;).

Sugestie?

Odpowiedz

7

Można po prostu wyprowadzić własne klasy strumieni od istream lub. ostream, ustaw bufor w konstruktorze i zniszcz go w destruktorze.

Coś jak:

class config_istream : public std::istream { 
public: 
    config_istream(std::string name) : 
     std::istream(fslib.InputStream(name.c_str())) 
    { 
    } 

    ~config_istream() { delete rdbuf(); } 
}; 

Wystarczy popatrzeć na to, jak fstream zajęcia są realizowane, mają do czynienia z podobnym problemem (filebuf musi być usunięty razem z fstream)

+0

Tak, jak powiedziałem przez Koniec pytania, myślę, że będę musiał to zrobić. Chciałem tylko wiedzieć, czy był jakiś łatwiejszy sposób, aby to zrobić XD Dzięki –

Powiązane problemy