2014-12-09 30 views
5

W normalnych okolicznościach wiem, jak dbać o przydział pamięci. Mój przypadek jest trochę inny.operator delete - jak zaimplementować?

Wdrażam własną pulę pamięci. Chciałbym, aby klient z mojej klasy był tak blisko ogólnej metody alokacji i de alokacji.

inline void* operator new(size_t dead_param, CPool& objPool) 
{ 
    return objPool.Allocate(); 
} 

mam tej globalnej funkcji, dzięki czemu użytkownik z mojej klasy może po prostu zadzwonić

Base baseObj = new (poolObj)Base2();

Teraz nie wiem jak wywołać destruktor? clearl nie mam pojęcia

chociaż mam globalny operator delete

inline void operator delete(void* ptr, CPool& objPool) 
{ 
    objPool.DeAllocate(ptr); 
} 

prosimy kierować .. jak mogę dostać tę funkcję o nazwie z kodu klienta? Z minimalnymi zmianami składni ze strony użytkownika. Zauważ też, że nie chcę, aby użytkownicy mojego kodu implementowali operator new i operator delete i dzwonili pod numer Allocate i i .

+0

Dlaczego po prostu nie mają ludzie nazywają 'base * baseObj = poolObj.Allocate();' – Barry

+0

Składnia dla klienta wydaje się trochę brzydka. 'Base * baseObj = (Base *) poolObj.Allocate()'. Yuck ... typecasting ... że chociaż zachowałem się jako ostateczny ośrodek ... Ponieważ nie jestem w stanie uzyskać tej funkcji, jestem teraz chory ... – Adorn

+5

Usunięcie miejsca docelowego jest wywoływane tylko z nowego miejsca docelowego new, gdy konstruktor wychodzi z wyjątek. We wszystkich innych przypadkach wywoływany jest "normalny" operator delete (void *). Powinieneś przechować wystarczającą ilość informacji w przydzielonym bloku pamięci, aby móc później zwolnić, bez dodatkowych danych wejściowych. Często alokator zapisuje dodatkowe informacje w ujemnym przesunięciu względem wskaźnika, który zwraca. –

Odpowiedz

1

Krótka niego: Dzięki umieszczeniu nowego to jedyny przypadek, w którym jawne wywołanie destruktora jest OK:

baseObj-> ~ bazowa();

Ale wydaje się to nieporęczne, ponieważ dzięki puli pamięci, użytkownik końcowy sprawia, że ​​wszystkie książki są przechowywane ... to sprawia, że ​​klasa pamięci nie jest lepsza (i prawdopodobnie nieco gorsza) niż po prostu używanie std :: vector.

nie miałbym zrobić użytkownikowi umieszczenie nowy sami ... raczej, jeśli dostarczanie własną pulę pamięci, to powinno być zrobione withing klasę ObjectPool:

class ObjectPool { 
    public: 
    template <typename T, typename... A>/*c++ 11 ftw*/ 
    T* allocate(A... args) { 
     void* create_location;//pool figures out where this is, probably with sizeof<T> 

     return new (create_location) T(args...); 
    } 
    template <typename T> 
    void dellocate(T* t) { 
     t.~T();//With placement new, this is the one place this is OK 
     //pool marks that memory as avaiable to be allocated in 
    } 
} 

Szczerze mówiąc, jest to jedyny sposób, aby Twoja pula miała więcej użyteczności niż końcowy użytkownik, robiąc po prostu swoją własną std::vector<uint8_t>.

Należy zauważyć, że nie robi nic, aby utrzymać T od przydzielania niczego innego na stercie ...

+0

ok .. prawdopodobnie możesz mnie oświecić więcej na temat projektu http://stackoverflow.com/questions/27375620/generic-memory-pool-how-to-design-issue Nie do końca rozumiem, co chcesz powiedzieć – Adorn