C++/Przeciążanie operatorów: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
operatory new i delete
Gbaz (dyskusja | edycje)
→‎New i delete: - opis dodatkowo new[] i delete[], dodanie opisu, dodanie przeciążania globalnego- w oparciu o "Symfonię C++"
Linia 221:
</noinclude>
=== New i delete ===
Są to operatory traktowane jako metody statyczne klas (niezależnie czy napiszemy słówko '''static''' czy nie), przykład:
<source lang="cpp">
class Foo {
Linia 229:
return (new char[rozmiar]); // zawarte tutaj new skorzysta z GLOBALNEGO (dla wszystkiego tworzonego za jego pomocą) operatora new
}
void operator delete(void* wsk) { // ta funkcja nic nie zwraca
delete wsk;
}
Foo(int j = 0) : i(j) {}
void* operator new[](size_t rozmiar) {
return (new char[rozmiar]); // należy pamiętać aby nasz obiekt miał koniecznie konstruktor bezargumentowy
}
void operator delete[](void* wsk) {
delete[] wsk;
}
};
</source>
Kilka uwag:
1. Operatory new i new[], oraz delete i delete[] nie są przemienne, czyli jak zdefiniujemy własny new to new[] jest nadal domyślny.
2. Mimo zdefiniowania własnego operatora new i delete możemy nadal używać globalnych wersji:
<source lang="cpp">
Foo *f1 = new Foo(); // wywoła naszą wersję
Foo *f2 = ::new Foo(); // wywoła wersję globalną
</source>
 
Kiedy może się nam przydać własny operator new i delete? M. in. jak chcemy alokować za pierwszym razem większą pamięć a potem tylko zwracać wskaźnik do następnego jej fragmentu.
Może być też przydatne gdy chcemy mieć kontrolę utworzenia jednej instancji obiektu.
---------
W powyższym przykładzie pokazałem jak przeciążyć ten operator dla własnej klasy, natomiast jest jeszcze możliwość przeciążenia globalnego, czyli dla każdego obiektu w programie od jego uruchomienia do wyłączenia -odpowiedzialność jest więc wielka.
Musimy się też liczyć z tym że w obrębie definicji nie możemy zrobić wszystkiego, czyli m.in. nie możemy używać strumieni cout (one korzystają z operatora new), oczywiście kompilator nie zaprotestuje natomiast podczas wykonania programu pojawi się problem.
Przykład:
<source lang="cpp">
#include <cstdlib> // biblioteka zawierająca funkcje malloc() i free()
 
void* operator new(size_t rozmiar) {
void* wsk = malloc(rozmiar);
return wsk;
}
void operator delete(void* wsk) {
free(wsk);
}
void* operator new[](size_t rozmiar) {
return wsk;
}
void operator delete[](void* wsk) {
free(wsk);
}
</source>
Autor "Symfonii C++", na której się opieram pisząc o new i delete, stanowczo odradza przeciążanie tego operatora globalnie