Przeczytałem gdzieś w jednej z odpowiedzi na pytanie tutaj (nie pamiętam, które), że C ++ nie nadaje się do programowania obiektowego. Było kilka wzmianek, że możesz skorzystać z jego funkcji lub czegoś takiego, ale nie w czysto OOP (tak naprawdę nie rozumiałem, co ta osoba ma na myśli).
Czy jest w tym jakaś prawda; jeśli tak to dlaczego?
c++
object-oriented
gablin
źródło
źródło
Odpowiedzi:
Jak opisano w Więc co * naprawdę * Alan Kay naprawdę miał na myśli termin „obiektowy”? Alan Kay pomyślał, że przekazywanie wiadomości było ważnym elementem OOP, ale jest to fragment, którego brakuje „C z klasami” (które później stały się C ++). C ++ to po prostu struktury z odrobiną zachowania, podczas gdy obiekty w Smalltalk lub Objective-C są „inteligentne”, ponieważ mogą decydować, co zrobią z wysłanymi wiadomościami. Jeśli obiekt Smalltalk otrzyma komunikat, dla którego nie ma implementacji, może leniwie dodać jeden, przekazać wiadomość do innego obiektu lub wykonać dowolną czynność.
C ++ oferuje w zakresie orientacji obiektowej
virtual
metody i polimorfizm związane ze sposobem wywoływania tych metod. Gdy kompilator zobaczy typ danych (lubclass
), który ma metody wirtualne, konstruuje vtable z miejscem dla każdej metody wirtualnej. Podklasy, które implementują metody wirtualne, umieszczą swoje implementacje w odpowiednich gniazdach, więc kod klienta musi jedynie wiedzieć, gdzie w wirtualnej tabeli szukać kodu do uruchomienia, zamiast rozwiązywać go aż do konkretnej funkcji. Co to znaczy jest, że C ++ skutecznie robi mieć postać stwardnienia wysyłki, chociaż to wszystko jest realizowane w kompilator i nie jest jako zdolny jako system Smalltalk-esque.Jeśli uważasz, że przekazywanie wiadomości ma podstawowe znaczenie dla OOP, to mimo że możesz to zrobić w C ++, nie jest to łatwe. OTOH, jeśli weźmiesz pod uwagę OOP jako powiązanie danych z funkcjami, które działają na tych danych, C ++ jest w porządku.
źródło
Tego rodzaju dyskusja niepokoi mnie, ponieważ brzmi to jak egzegeza, ludzie debatujący nad znaczeniem Pisma Świętego lub amerykańskiej konstytucji i co oryginalny autor (autorzy) mieli na myśli, tak jakby to , co myślimy, nie miało znaczenia.
Słuchaj, Alan Kay był / jest sprytnym facetem i miał dobry pomysł, który zatarł wiele innych dobrych pomysłów i został zrealizowany w Smalltalk i innych językach.
On nie jest Mesjaszem, a OOP nie jest jedynym prawdziwym paradygmatem programowania.
Jest to dobry pomysł spośród wielu. Czy C ++ ma dobre pomysły, wywodzące się z sposobu myślenia OOP? Oczywiście, że tak.
źródło
C ++ obsługuje OOP, jeśli zdefiniujesz OOP jako enkapsulację, dziedziczenie i polimorfizm.
Jednak C ++ tak naprawdę nie przoduje w OOP. Jednym z powodów jest to, że polimorfizm często zależy od obiektów alokowanych na stercie, które (bez względu na użycie inteligentnych wskaźników) są bardziej naturalne do pracy w języku zbierającym śmieci.
Jednak tam, gdzie C ++ przoduje, jest programowanie ogólne. C ++ pozwala łatwo tworzyć wysoce wydajny, ogólny kod za pomocą technik programowania funkcjonalnego opartych na szablonach.
źródło
C ++ pożyczył funkcje OOP od Simula. Jeden lub więcej deweloperów Simula IIRC skomentowało, że C ++ nie jest tym, co mieli na myśli.
C ++ ma dobre narzędzia do abstrakcji, ale jest to bardziej język mieszany paradygmat niż język obiektowy. Istnieją obiekty zorientowane obiektowo, ale masz opcje, które nie są „ścisłym OOP”.
Jednym z niegrzecznych „rezygnacji”, jakie otrzymujesz w C ++, jest stosowanie wcześniejszego niż późnego wiązania dla metod. Jest to nie tylko możliwe - jest to ustawienie domyślne. W Javie „końcowy” jest powiązany, ale pod pewnymi względami bardziej przejrzysty (określa intencję w sposób, który nie polega tylko na unikaniu trywialnego narzutu wydajności) i nie jest domyślny.
W pewnym sensie C ++ wykazuje oznaki bycia wczesnym eksperymentem, który wciąż tu jest. Mimo to jest to nadal dobre narzędzie z wieloma zaletami, których nie można uzyskać w innych językach OOP.
źródło
Wymuszanie, by wszystko było częścią klasy, niekoniecznie daje wspaniały kod OO.
Poproś biednego programistę proceduralnego, aby programował w Javie, a prawdopodobnie zabiorą gdzieś klasę, nadadzą jej statyczną metodę główną i wstawią do niej 1000 linii kodu. Wiem, że to widziałem.
Java ma instrukcję switch. Widziałem
switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }
itp. Zarówno w kodzie C ++, jak i Java.C ++ obsługuje wiele koncepcji OO, ale jego standard nie jest przez nią zdefiniowany, ale myślę, że wiele zależy od tego, jaki jest twój cel.
Główny „słaby” semantyczny w C ++ pozwala na kopiowanie konstrukcji klas, dzięki czemu obiekt przekształca się w inny. Możesz to wyłączyć, ale nie możesz zwrócić żadnej z funkcji. Na szczęście jest to rozwiązane w C ++ 0x.
źródło
OOP nie polega tylko na upewnieniu się, że wszystko jest w klasie. Zupełnie możliwe jest pisanie kodu innego niż OO w języku „czysto OO”. Na przykład „main” jest często wskazywane jako funkcja globalna, ale wynalezienie klasy zawierającej wyłącznie statyczną metodę główną jest tak samo niemożliwe.
C ++ działa najlepiej z wieloma różnymi rzeczami; nie powinno to być zaskakujące, ponieważ tak najlepiej działa większość dobrych rzeczy. Często OOP jest jednym z tych bardzo przydatnych narzędzi.
źródło
C ++ może być używany do OOP, ale nie jest tak „czysty” jak coś takiego jak Smalltalk. C ++ pozwala także na wykonywanie zadań bez OOP, o czym ludzie mogą mówić.
źródło
Chociaż nie zgadzam się z tym sentymentem, prawdą jest, że system typów C ++ nie jest czystym OOP - nie „wszystko jest przedmiotem”. Liczby (w szczególności) nie mogą być przedłużane tak łatwo, jak to możliwe, powiedzmy w Smalltalk. Na przykład nie można przedefiniować znaczenia „2 + 2” (chociaż można przedefiniować znaczenie „dwa + dwa”).
Ale większość ludzi prawdopodobnie ma na myśli to, że wiele osób pisze w języku C ++ kod nieobiektywny, ale wierzy, że ponieważ używają języka „OOP”, są zorientowani obiektowo. To nieprawda. Ale moim zdaniem możesz pisać ohydny imperatywny kod w Smalltalk i nie być lepszym od przyzwoitego projektu OOP w C ++.
źródło
Całkowicie uzasadnionym zastrzeżeniem Alana Kay'a do C ++ było to, że był to język makro na C.
Pojęcie „przekazywanie wiadomości” jest po prostu ideą, że instancje klas są przechowywane w pamięci i ujawniają metody, które można wywołać. Przekazywanie wiadomości jest * symulowane "w C ++ przy użyciu vtables przechowujących wskaźniki do funkcji.
Stwierdzenie, że przekazywanie wiadomości nie istnieje w C ++, jest niedokładne, dokładniejsze jest stwierdzenie, że przekazywanie wiadomości jest integralną częścią innych języków, takich jak smalltalk i Java, ponieważ język nie przetwarza obcego konstruktu i przenosi go bezpośrednio na język C.
Jest to wysoce semantyczny argument projektowania języka, który, jak podejrzewam, wykracza nieco poza poziom doświadczenia pytającego.
Biorąc to pod uwagę, istnieje tysiące powodów, aby nienawidzić C ++ i bardzo niewiele powodów, by go kochać.
Zamiast szukać idealnego młotka i idealnego gwoździa, znajdź idealny dom do zbudowania, a następnie znajdź odpowiednie narzędzia ... które wymagają doświadczenia.
Ważne jest również, aby pamiętać, że w programowaniu systemów, czego obawia się Alan Kay, nie jest „czysty OOP”, tak naprawdę jest siłą C ++. Do każdej jego własności...
źródło
Moim zdaniem nie jest to kwestia definicyjna, ale kwestia użyteczności.
Obiekty są abstrakcją mającą na celu ułatwienie czytania, pisania i rozumowania złożonych programów. Dla praktycznego programisty to, czy język spełnia wszystkie kryteria określonej formalnej definicji „obiektowej” (wydaje się, że istnieje kilka konkurencyjnych!), Nie jest tak ważne, jak to, czy oferowane przez nią narzędzia są odpowiednie do myślenia o twój program pod względem wspomnianych obiektów - tj. faktycznie czerpiąc przypuszczalne korzyści OOP związane z produktywnością.
W C ++ obiekty są strasznie nieszczelnymi abstrakcjami, często zmuszając programistów do kłótni z nieprzyjemnymi problemami związanymi ze strukturą tych obiektów w pamięci - problemami bardziej przypominającymi kodowanie w prostym języku C niż w innych językach OOP. Na przykład C ++ Często zadawane pytania oferuje taką krytykę (między innymi):
C ++ jest zorientowany obiektowo, ale nieprzyjemnie i niekompletnie: jego użytkownicy muszą poświęcić wiele wysiłku, aby upewnić się, że ich dane faktycznie zachowują się jak „prawdziwe” obiekty, a nie błędne bity. To powiedziawszy, wiele kodu zostało napisanych w C ++ przez cały okres jego życia, większość z nich korzysta z klas i dynamicznej wysyłki, więc jest to oczywiste coś, co można wykorzystać do praktycznego OOP.
źródło
Jest powód, dla którego Graham Lee miał tutaj najwięcej pozytywnych opinii. Powtarzając, wydaje się, że klasa C ++ nie jest tak naprawdę obiektem w tym sensie, że nie wykonuje przekazywania wiadomości. Myślę, że to bardzo podoba ludziom, kiedy uczą się C ++ lub oop. Ludziom mówi się, że obiektowe jest „to”, a następnie mówi się, że C ++ robi to inaczej. C ++ nigdy nie robił inaczej OOP. Jeśli myślisz w ten sposób, nigdy nie docenisz klas C ++ za to, do czego są przeznaczone, a to dlatego, że stanowią jedynie ulepszenie paradygmatu proceduralnego poprzez włączenie abstrakcji i zachowania dynamicznego. Tak więc klasy C ++ są z zasady proceduralne, po prostu poprawiają paradygmat proceduralny, a raczej są bardziej zaawansowaną wersją struktury C.
źródło
Steve Yegge powiedział najlepiej :
System obiektu w C ++ jest tak ciężko przewodowych i stałe w czasie kompilacji, że to jest bardzo odległe od pierwotnego pojęcia OOP, który obejmuje wiadomości z pominięciem, introspekcji, refleksji, dynamiczny wysyłce i późne wiązanie, między innymi. Jedyne, co łączy C ++ i Smalltalk, to trochę słownictwa.
źródło