2017-08-30 73 views
5

Załóżmy, że implementujemy niestandardową kolekcję, która zachowuje się jak wektor i chcemy, aby operator[] rzucił wyjątek, jeśli kolekcja jest pusta. std::vector ma niezdefiniowane zachowanie w tym przypadku, ale chcemy rzucić wyjątek. Jeśli byłby to C#, prawdopodobnie wyrzucilibyśmy InvalidOperationException. Ale który z nich byłby najbardziej odpowiedni/intuicyjny w tym przypadku? Czuję, że std::out_of_range nie byłby najlepszym wyborem, ponieważ kolekcja jest pusta, więc nie ma "zakresu", dla którego indeksowanie zwróci ważny (dowolny element).Który wyjątek do rzucania, gdy obecny stan obiektu nie pozwala na próbę operacji na nim?

+2

Właściwie myślę, że 'std :: out_of_range' byłby rzeczywiście wyjątkiem, którego bym użył. Jeśli kontener jest pusty, oznacza to, że indeks jest poza zakresem, tak samo zachowuje się już polecenie "std :: vector". Pamiętaj, że pusty zestaw nadal jest zbiorem (w sensie matematycznym). – CoryKramer

+0

IMHO Myślę, że każdy zrozumie twoje użycie 'std :: out_of_range'. Nawet odnośnik do strony, do której się łączysz * Definiuje typ obiektu, który ma być zgłoszony jako wyjątek. Zgłasza błędy będące konsekwencją próby dostępu do elementów poza zdefiniowanym zakresem. * Co całkiem dobrze pasuje do tej sytuacji. – NathanOliver

+2

'Wektor :: at' rzuci' std :: out_of_range', gdy wektor jest pusty, więc uważam, że jest to rzeczywiście poprawny wyjątek. – SirDarius

Odpowiedz

4

std::vector::at już to robi. Więc możesz użyć metody at zamiast operator []. Rzuca std::out_of_range dla nieprawidłowego indeksu.

Należy pamiętać, że aby uzyskać wydajność std::vector, należy wykonać znaczne prace. Ale nadal, jeśli chcesz trzymać się swojego własnego pojemnika i chcesz rzucić od [], to taki sposób jak at jest najlepszym wyborem spośród standardowych klas wyjątków. W przeciwnym razie musisz zdefiniować własną niestandardową klasę wyjątków.

+1

Dzięki @taskinoor. Wdrażam tę niestandardową kolekcję jako ćwiczenie ... więc było to bardziej hipotetyczne pytanie. Zdecydowanie uniknęłbym tego w przypadku oprogramowania komercyjnego/produkcyjnego, chyba że miałby ku temu dobry powód. –

+1

@BojanKomazec do celów edukacyjnych jest całkowicie w porządku, IMHO. Off topic comment: spójrz na 'std :: allocator', którego możesz potrzebować, aby uniknąć niepotrzebnego wywoływania domyślnych konstruktorów i przenieść semantykę, która może być potrzebna do efektywnego wzrostu operacji. – taskinoor

Powiązane problemy