W C++ operator new i operator delete to funkcje przydzielania i zwalniania pamięci, które są wywoływane podczas tworzenia i usuwania obiektów za pomocą operatorów new i delete. Domyślnie używają standardowego alokatora, ale w klasie można je przeciążyć, aby uzyskać bardziej precyzyjną kontrolę nad przydzielaniem pamięci.
operator new przydziela "surowy" obszar pamięci, nie wywołując konstruktora.operator delete zwalnia pamięć po zakończeniu destruktora obiektu.operator new w klasie, można zoptymalizować działanie z pamięcią dla obiektów tej klasy (np. pula obiektów, śledzenie, ponowne użycie bloków).#include <iostream> class TrackAlloc { public: void* operator new(size_t size) { std::cout << "TrackAlloc::new dla " << size << " bajtów "; return ::operator new(size); } void operator delete(void* ptr) { std::cout << "TrackAlloc::delete "; ::operator delete(ptr); } };
"Co się stanie, jeśli przeciążę operator new w klasie, a następnie stworzę obiekt przez zmienną odziedziczonej klasy? Która wersja operatora new zostanie wywołana?"
Odpowiedź: Zostanie wywołany operator new klasy, której imienia używa się do tworzenia obiektu. Jeśli klasa pochodna nie ma zaimplementowanego operatora new, nastąpi próba znalezienia odpowiedniej wersji w klasie bazowej lub wersji globalnej.
Przykład:
struct Base { void* operator new(size_t s) { std::cout << "Base new "; return ::operator new(s); } }; struct Derived : Base {}; Derived* p = new Derived; // Wywoła Base::operator new!
Historia
Programiści przeciążyli operator new/delete bez wsparcia dla prawidłowej obsługi wyjątków. Przy wyrzuceniu wyjątku w konstruktorze pamięć nie była zwalniana, co prowadziło do wycieków pamięci.
Historia
Niepoprawnie zaimplementowano operator new[] i operator delete[]: dla klasy, w której zawarte były tablice, nowa implementacja nie była wywoływana — używane były domyślne wersje, co prowadziło do niesynchronizacji logiki przydzielania i zwalniania pamięci.
Historia
Przeciążenie globalnego operatora new wpłynęło na działanie zewnętrznych bibliotek: wszystkie obiekty (w tym tymczasowe i z STL) zaczęły być alokowane przez alokator z logowaniem, co krytycznie spowolniło działanie rdzenia aplikacji.