2011-08-21 3 views

Odpowiedz

10

Po przeczytaniu tego samouczka, nieco mnie zdezorientował sam tekst. Ale wierzę, że to tak proste, jak to: samouczek wyjaśniał dlaczego szablon nagłówka podzielnika pokazuje

allocator(const allocator&) throw();

i

template <class U> allocator(const allocator<U>&) throw();

mimo że konstruktor kopia jest dość bezużyteczny dla podzielnika. Odpowiedź była taka, że ​​specyfikacja programu przydzielającego nie pozwala konstruktorowi zgłaszać wyjątków. Dlatego też publiczny interfejs konstruktora kopii definiuje konstruktorów kopii ze specyfikacją wyjątku throw() (nie wyrzuca żadnych wyjątków), aby uniemożliwić komuś wyprowadzenie własnego alokatora z konstruktorami kopii, który mógłby rzucić wyjątek.

Zapoznaj się z this link, aby uzyskać dokładny opis specyfikacji wyjątku, jeśli właśnie go rzuciłeś. (Naprawdę nie grał.) Naprawdę.)

Nie oznaczało to, że przy tworzeniu alokatora konieczne jest podanie konstruktora kopii. Po prostu wskazywali, że specyfikacja wyraźnie zabrania definiowania takiego, który rzuca jakiekolwiek wyjątki. `

1

Przydzielacz wymaga konstruktora kopii, ponieważ kontenery mają konstruktora kopii i będą musiały skopiować swój alokator w procesie.

+1

Przed C++ 11, przydziały były koniecznie bezpaństwowcami. W związku z tym wystarczyłoby wywołanie do domyślnego konstruktora.Post C++ 11, czy alokatory są kopiowane przez ich otaczające kontenery w danej sytuacji, zależy od obecności i definicji metod alokacji "select_on_container_X_Y". Zobacz [referencje cech przydzielających] (http://en.cppreference.com/w/cpp/memory/allocator_traits) – apmccartney

4

Musisz jawnie napisać konstruktor kopii (zamiast używać domyślnego), ponieważ konstruktor kopii dla alokatora C++ 03 musi być zdefiniowany za pomocą specyfikatora wyjątków throw(). Domyślny konstruktor kopiowania nie ma tego specyfikatora.

Pod względem technicznym nie musisz mieć numeru, ale jeśli spowoduje to wyjątek ... cóż, powodzenia z tym.

Ale to tylko drobna irytacja, ponieważ alokatory w C++ 03 nie mogą mieć stanu. Więc nie powinieneś kopiować członków w pobliżu. Konstruktor kopiowania może być pusty.

+1

Nicol Bolas, czy będzie dobrze, jeśli alokator (const allocator &) = delete ;? jak jesteśmy w 2016 roku –

0

Jest to całkiem proste. Konstruktor kontenera za pomocą alokatora pobiera alokator i przechowuje jego kopię. Aby to zrobić, potrzebny jest alokator, który ma być CopyConstructible. To wszystko. Należy zauważyć, że typ przydziału nie jest wymagany do CopyAssignable, chyba że jego właściwość propagate_on_container_copy_assignment jest prawdziwa (co jest rzadkie).

Specyfikacja C++ 11 również stwierdza, że ​​"Żaden konstruktor, operator porównania, operacja kopiowania, przenoszenia lub operacji zamiany na tych typach nie powinien wychodzić z wyjątku." Reguły wyjątków pozwalają na wykonanie (stos) kopii alokatora (szczególnie podczas budowy lub zniszczenia) bez obawy, że skopiowanie alokatora zostanie rzucone. Projektowanie pojemników, które są wyjątkowo bezpieczne w obecności alokatorów, które mogą rzucać na kopie, przesuwać, zamieniać lub porównywać jest prawie niemożliwe. W praktyce alokator nie może posiadać o wiele więcej niż wskaźnika do jakiegoś zasobu, więc pozwalając alokatorom na rzucanie na kopię itp., Spowodowałoby wiele bólu, praktycznie bez zysku.