Posiadam klasę podstawową, która nie jest polimorficzna, ale chcę uniemożliwić jej utworzenie. Czy powinienem dać tej klasie bazowej czysty wirtualny destruktor, aby uniemożliwić jego utworzenie? Ale czy niewłaściwą lub złą praktyką jest nadanie nie-polimorficznej klasie podstawowej wirtualnego destruktora?Zapobieganie powstawaniu klasy bazowej, która nie jest polimorficzna C++
Odpowiedz
Aby zapobiec tworzeniu instancji klasy bazowej, należy utworzyć konstruktory protected
.
To prawda, dzięki. Ale to daje mi kolejne pytanie, czy mogę po prostu uczynić wszystkich konstruktorów chronionymi w klasie, aby uniemożliwić ich utworzenie, dlaczego w ogóle mieliby powstać klasy abstrakcyjne? – pkdc
@pkdc Aby wymusić zastąpienie funkcji. – nwp
To są różne przypadki. Klasa staje się abstrakcyjna w C++, deklarując jednego z jej członków, aby był "czystym wirtualnym", czyniąc go przede wszystkim * niekompletną * klasą. Właśnie dlatego C++ nie potrzebuje słowa kluczowego 'abstract', ponieważ może ono zostać automatycznie odroczone z obecności co najmniej jednego czystego wirtualnego. W twoim przypadku jednak klasa jest funkcjonalnie * kompletna *, po prostu nie powinna być tworzona z innych powodów. Co stanowi oczywiste rozwiązanie, które uniemożliwia wywoływanie konstruktora. –
Klasy bazowe w C++ są zalecane do uprawiania wirtualnego destruktora. C++ to naprawdę stary język programowania, a w przypadku braku wirtualnego destruktora obiekt klasy pochodnej mógłby zostać częściowo lub niepoprawnie zniszczony.
Oczywiście, czysty wirtualny destruktor uniemożliwi tworzenie dowolnych wystąpień tej klasy, ale myślę, że aby wyjaśnić, że nie spodziewasz się, że ta klasa zostanie utworzona, możesz również utworzyć konstruktorów protected
, jak podkreślił @Niels w swojej odpowiedzi.
Mam nadzieję, że to pomoże.
* "C++ jest naprawdę starym językiem programowania, a w przypadku braku wirtualnego destruktora obiekt klasy pochodnej mógłby zostać częściowo lub niepoprawnie zniszczony." * - C++ ma solidne powody, dla których nie wszystkie wirtualne destruktory są wirtualne - wydajność, Zgodność układu binarnego, użyteczność w pamięci współdzielonej itp. - nie ma nic wspólnego z "byciem starym", a implikacja, że starszy język jest w jakiś sposób nieodłącznie zagrożona, jest wadliwa. –
O, kochanie. Myślę, że nieświadomie stworzyłem wojnę o płomienie. Przepraszam, nie zgadzam się. C++ jest rzeczywiście bardzo starym językiem programowania, kiedy kompilator musiał dużo kompromitować w korzystaniu z pamięci i wydajności. Dlatego logiczne było pozostawienie wielu decyzji programistom. To już nie jest prawda, a kompilator powinien być dużo mądrzejszy niż jest teraz. Efektywność i inne sprawy mogą być automatycznie obsługiwane, nie jest to takie trudne. W końcu robi to wiele obecnych języków programowania. Och, a C++ nie jest zagrożone. Musisz dokładnie wiedzieć, co robisz. – Baltasarq
@Baltasarq Muszę również nie zgodzić się z twoją opinią w tej sprawie. C++ jest nadal w użyciu ** ponieważ ** skupia się na wydajności i całej mocy, jaką pozostawia programistom. C++ był aktualizowany kilka razy od czasu jego powstania w 1978 roku i nadal pozwala na użycie nie wirtualnych destruktorów, ponieważ jego nieograniczona swoboda działania jest głównym powodem, dla którego wciąż istnieje powód do życia.Jeśli piszesz program, który nie wymaga ręcznej kontroli nad takimi decyzjami, C++ nie jest po prostu odpowiednim narzędziem i powinieneś używać C# lub Java zamiast tego. Jeśli wydajność jest istotna, C i C++ nadal są * odpowiednimi narzędziami do pracy *. –
Trzymaj ctor/dtor w chronionym zasięgu.
- 1. Zapobieganie powstawaniu lśnienia przez aktualizowanie elementów sprytnie
- 2. Dlaczego ta metoda podklasy nie jest polimorficzna?
- 3. C++ unikając ręcznie wywołanie klasy bazowej funkcji
- 4. Wywołanie klasy bazowej metoda
- 5. Metoda klasy, która nie jest w interfejsie
- 6. C#: Konwersja klasy bazowej do dziecka Klasa
- 7. Która klasa pobiera raport getClass() wewnątrz konstruktora klasy bazowej
- 8. Dziedziczenie z jednej klasy bazowej, która implementuje INotifyPropertyChanged?
- 9. unique_ptr do klasy bazowej
- 10. weak_ptr z klasy bazowej, podczas gdy shared_ptr jest klasy pochodnej?
- 11. Definiowanie klasy Objective-C bez klasy bazowej - Ostrzeżenie o kompilatorze
- 12. Different inicjalizacji atrybutu klasy bazowej
- 13. Czy można zapobiec powstawaniu "anonimowo" klasy w stylu RAII?
- 14. wirtualnej klasy bazowej wywołuje pusty konstruktor w C++ (C++ 11)
- 15. Wywołanie klasy bazowej za
- 16. Objective-C: Jak przekazać obiekt jako argument bloku do metody, która oczekuje swojej klasy bazowej?
- 17. Nie można obniżyć, ponieważ klasa nie jest polimorficzna?
- 18. Hibernate polimorficzna instrukcja SELECT HQL
- 19. Przypisywanie klasy pochodnej do klasy bazowej
- 20. Polimorficzna kopia w Javie
- 21. Rozszerzanie delegata z klasy bazowej
- 22. maszynopis dostępu członkiem klasy bazowej
- 23. Python - Testowanie abstrakcyjnej klasy bazowej
- 24. MethodCallExpression.Method zawsze zwraca MethodInfo klasy bazowej root
- 25. Niejawne wywoływanie konstruktora niedostępnej wirtualnej klasy bazowej
- 26. Dziedziczenie z nazwanej, pomniejszej klasy bazowej - Python
- 27. Funkcja polimorficzna Java Higher Order
- 28. Jak mogę pobrać typ klasy bazowej w C++?
- 29. Korzystanie zmienne składowe dziedziczone z matrycy klasy bazowej (C++)
- 30. Członek dostępu klasy pochodnej od wskaźnika klasy bazowej
uczynienie destruktora prywatnym nie uniemożliwia utworzenia instancji klasy. – user463035818
możliwy duplikat [C++: jakikolwiek sposób, aby zapobiec powstaniu abstrakcyjnej klasy bazowej?] (Http://stackoverflow.com/questions/6272445/c-any-way-to-prevent-any-instantiation-of-an -abstract-base-class) –
jest trochę podobny do [wzorca singleton] (https://pl.wikipedia.org/wiki/Singleton_pattern) gdzie konstruktor jest prywatny, aby zapobiec tworzeniu więcej niż jednego obiektu z instancji –