Czasami musisz napisać konstruktor, który może zawieść. Powiedzmy na przykład, że chcę utworzyć instancję obiektu ze ścieżką do pliku, coś w rodzaju
obj = new Object("/home/user/foo_file")
Dopóki ścieżka wskazuje odpowiedni plik, wszystko jest w porządku. Ale jeśli łańcuch nie jest prawidłową ścieżką, rzeczy powinny się zepsuć. Ale jak?
Mógłbyś:
- rzuć wyjątek
- zwróć obiekt zerowy (jeśli twój język programowania pozwala konstruktorom zwracać wartości)
- zwraca poprawny obiekt, ale z flagą wskazującą, że jego ścieżka nie została ustawiona poprawnie (ugh)
- inni?
Zakładam, że „najlepsze praktyki” różnych języków programowania wdrażałyby to inaczej. Na przykład myślę, że ObjC woli (2). Ale (2) byłoby niemożliwe do zaimplementowania w C ++, gdzie konstruktory muszą mieć void jako typ zwracany. W takim przypadku przyjmuję, że użyto (1).
Czy w wybranym języku programowania możesz pokazać, jak poradzisz sobie z tym problemem i wyjaśnić, dlaczego?
constructors
initialization
garażtrois
źródło
źródło
void
- zwracają obiekt.new
wywołujeoperator new
alokację pamięci, a następnie konstruktor, aby ją wypełnić. Konstruktor nic nie zwraca inew
zwraca wskaźnik, który otrzymałoperator new
.void
Jednak to, czy „nic nie zwraca” oznacza, że „zwraca ”, jest do zdobycia.Odpowiedzi:
Nigdy nie warto polegać na konstruktorze, który wykonuje brudną robotę. Poza tym dla innego programisty nie jest jasne, czy w konstruktorze będzie wykonywana praca, chyba że istnieje wyraźna dokumentacja, że tak jest (i że użytkownik klasy ją przeczytał lub o tym powiedział).
Na przykład (w języku C #):
Co się stanie, jeśli użytkownik nie chce od razu załadować pliku? Co jeśli chcą wykonać buforowanie pliku na żądanie? Nie mogą. Możesz pomyśleć o wstawieniu
bool loadFile
argumentu do konstruktora, ale powoduje to bałagan, ponieważ nadal potrzebujeszLoad()
metody wczytywania pliku.Biorąc pod uwagę obecny scenariusz, użytkownicy klasy będą bardziej elastyczni i jaśniej:
Lub alternatywnie (dla czegoś takiego jak zasób):
źródło
W Javie możesz użyć wyjątków lub wzorca fabrycznego, który pozwoli ci zwrócić wartość null.
W Scali możesz zwrócić opcję [Foo] z metody fabrycznej. To też działałoby w Javie, ale byłoby bardziej kłopotliwe.
źródło
Rzuć wyjątek.
Należy sprawdzić wartość Null, jeśli możesz ją zwrócić (i nie będzie zaznaczona)
Do tego służą sprawdzone wyjątki. Wiesz, że to może zawieść. Dzwoniący muszą sobie z tym poradzić.
źródło
W C ++ konstruktory są używane do tworzenia / inicjowania członków klasy.
Nie ma właściwej odpowiedzi na to pytanie. Ale do tej pory obserwowałem, że w większości przypadków klient (lub ktokolwiek będzie korzystał z twojego API) wybiera sposób, w jaki powinieneś sobie z tym poradzić.
Czasami proszą przeznaczyć wszystkie zasoby, które mogą potrzebować obiekt na konstruktora i rzucić wyjątek, jeśli coś się nie powiedzie (przerywanie tworzenie obiektu), czy nic z tego na konstruktora, i upewnij się, że kreacja będzie zawsze uda , pozostawiając te zadania do wykonania przez funkcję członka.
Jeśli to Ty wybierasz zachowanie, wyjątki są domyślnym sposobem obsługi błędów w C ++ i powinieneś ich używać, kiedy tylko możesz.
źródło
Możesz także utworzyć obiekt bez parametrów lub tylko z parametrami, które z pewnością nigdy nie zawiodą, a następnie użyjesz funkcji lub metody inicjalizacji, dzięki której możesz bezpiecznie zgłosić wyjątek lub zrobić wszystko, co chcesz.
źródło
Wolę nie inicjować żadnej klasy ani listy w konstruktorze. Zainicjuj klasę lub listę w dowolnym momencie. Na przykład.
Nie rób tego
Zamiast tego zainicjuj, gdy jest to wymagane Np.
źródło