2010-02-25 11 views
8

To może być głupie pytanie dla niektórych z was i może zadałem to pytanie źle, ponieważ jestem nowy w C++. Ale zauważam, że pracując w wielu aplikacjach Win32, używasz wielu zasobów, które są wskaźnikami. Dlaczego zawsze musisz zdobyć wskaźnik obiektów? dlaczego nie zainicjować nowej instancji klasy. i mówiąc o tym, zauważam, że w większości przypadków nigdy nie inicjujesz nowych obiektów, ale zawsze wzywaj metody, które zwracają ten wskaźnik. Co jeśli ten wskaźnik jest używany gdzie indziej. nie mógłbyś coś zepsuć, jeśli zmienisz ten wskaźnik i będzie on używany gdzie indziej.Aplikacja win32 nie jest tak obiektowo zorientowana i dlaczego jest tak wiele wskazówek?

Odpowiedz

24

Interfejsy API systemu Windows zostały zaprojektowane dla języka C, który był i nadal jest najczęściej używanym językiem do programowania systemu; API C są de facto standardem dla API systemu, a do tego prawie wszystkie inne języki miały i mogły w jakiś sposób wywoływać zewnętrzne funkcje C, więc napisanie C API pomaga być kompatybilnym z innymi językami.

C Funkcje API wymagają prostego ABI, które składa się prawie z definicji konwencji wywołującej, która ma być używana dla funkcji (i co nieco z układu struktury). Natomiast C++ i inne języki obiektowe wymagają złożonej ABI, która musi określać sposób rozmieszczania obiektów w pamięci, jak radzić sobie z dziedziczeniem, jak rozkładać tabelę, jak propagować wyjątki, gdzie umieścić dane RTTI, ... Co więcej, nie wszystkie języki są zorientowane obiektowo, a używanie API uważanych za C++ z innymi językami nieobiektowymi może być prawdziwym bólem (jeśli kiedykolwiek używałeś COM z C, wiesz o co mi chodzi).

Jak na bok, gdy system Windows był początkowo zaprojektowany C++ nie był tak rozpowszechniony na komputerach, a także C nie użyto tak dużo: faktycznie, duża część z Windows 3.11 i wielu zastosowaniach wciąż napisany w montażu , ponieważ ograniczenia pamięci i procesora w epoce były bardzo wąskie; Kompilatory były również mniej inteligentne niż obecnie, zwłaszcza C++. Na komputerach, na których ręczne fałszowanie było często jedynym rozwiązaniem, narzut C++ był naprawdę nie do przyjęcia.

Do rzeczy wskazówek: Okna API używać prawie zawsze obsługuje, tj mętny wskaźnik, aby móc zmienić podstawową naturę każdego zasobu bez wpływu na istniejące aplikacje i zatrzymać aplikacje do bałaganu wokół struktur wewnętrznych. Nie ma znaczenia, czy struktura używana przez menedżera okien do wewnętrznego reprezentowania okna jest zmieniona: wszystkie aplikacje używają po prostu HWND, który ma zawsze wielkość wskaźnika. Możesz myśleć o tym jako o jakimś idiomie PIMPL.

Jednak system Windows jest w pewien sposób obiektowy (patrz na przykład cała koncepcja "klasy okna" lub, na głębszym poziomie, wewnętrzna praca jądra NT, która jest silnie oparta na "obiekcie" koncepcja), jednak najbardziej podstawowe API, będące prostymi funkcjami języka C, niejako ukrywają tę OO. Powłoka, z drugiej strony, zaprojektowana wiele lat później, jest napisana głównie w C++ i zapewnia naprawdę zorientowany obiektowo interfejs COM.

Co ciekawe, w COM można zobaczyć wszystkie kompromisy, z którymi trzeba się zmierzyć przy budowaniu wielojęzycznego, ale nadal zorientowanego obiektowo interfejsu C++: wynik jest dość skomplikowany, pod pewnymi względami brzydki i niezbyt prosty w użyciu dowolny język. Zamiast tego interfejsy API systemu Windows są prostszymi funkcjami, które łatwiej jest wywoływać.

Jeśli interesuje Cię system oparty na API C++, możesz rzucić okiem na Haiku; osobiście, jest to jeden z aspektów, z powodu których jestem bardzo zainteresowany tym projektem.

Nawiasem mówiąc, jeśli zamierzasz tworzyć programowanie Win32 tylko za pomocą API, lepiej zaopatrzyć się w dobrą książkę, aby przyzwyczaić się do tych "szczególnych" i do innych idiomów Win32. Dwa znane to: Rector-Newcomer i Petzhold.

+0

dzięki. ze wszystkich odpowiedzi. teraz ma o wiele więcej sensu. – numerical25

+0

Świetne wyjaśnienie. Jedno pytanie: czy Win32 jest w rzeczywistości zorientowany obiektowo, dlaczego tak trudno uzyskać wskaźnik instancji w funkcji WndProc (prawdopodobnie serce całego API)? (http://www.codeguru.com/forum/printthread.php?t=234315) –

+0

@Jared: bardziej lub mniej obiektowa charakterystyka Win32 API jest rzeczą koncepcyjną, która nie ma nic wspólnego z systemem typu C++. Klasy okien są pojęciem menedżera okien, a nie konkretnego języka używanego do uzyskiwania dostępu do funkcji WM. Możesz utworzyć powiązanie między klasami/obiektami C++ a klasami/instancjami okien, ale w zasadzie są to rzeczy zupełnie niepowiązane. –

1

Prawdopodobnie dlatego, że Win32 API jest "starszy" niż główny program obiektowy, nie jest to rdzeń API C++.

5

Win32 został zaprojektowany do pracy z językiem C, a nie C++.
Dlatego na przykład można zobaczyć typy zwrotu zdefiniowanego BOOL zamiast bool.
bool jest specyficzne dla C++ i nie istnieje w C

Dla obiektowego otoki Microsoft Win32 zobaczyć MFC.

Nowsza platforma firmy Microsoft od tego czasu to .Net Framework.
Framework .Net opiera się na kodzie zarządzanym i nie działa natywnie. Najnowocześniejszym sposobem programowania GUI w systemie Windows jest WPF lub nawet Silverlight.

Najnowocześniejszy sposób programowania niezarządzanego GUI nadal wykorzystuje MFC, chociaż niektórzy nadal wolą używać prostego Win32.

Uwaga Praca ze wskaźnikami nie jest specyficzna dla C, nadal jest bardzo powszechna w C++.

+2

MFC jest zbyt stary i źle zaprojektowany, nie polecam go używać ... – dimsuz

+1

@dpimka: Plakat pyta konkretnie o Win32. MFC znajduje się niedaleko Win32 i warto wspomnieć w tym kontekście. –

+3

MFC nadal jest _official_ OO sposób na Windows w C++, prawda? –

4

Po pierwsze dlatego, że wskaźniki przechodzenia są tanie. Wskaźniki mają 4 bajty na x86 i 8 bajtów na x64. Podczas gdy struktura lub klasa, do której ona wskazuje, może zajmować znacznie więcej w pamięci. Zatem tworzenie instancji klasy oznacza ponowne rezerwowanie nowej pamięci. Nie jest to efektywne z POV o prędkości i zużyciu pamięci.

Innym sposobem jest przekazywanie odniesień do obiektów lub inteligentnych wskaźników lub podobnych konstrukcji. Ale api win32 było zaprojektowane w erze C, więc to jest to, gdzie jest do tej pory;)

Co do potencjalnego zmyślenia ze wskaźnikami - to oczywiście możliwe. Ale przez większość czasu ich życie jest wyraźnie określone w API (jeśli nie jest oczywiste).

-3

Aby zrozumieć wskaźniki, możesz przeczytać the CPlusPlus.com tutorial on pointers.

+0

Rozumiem wskaźniki. Po prostu nie rozumiem, dlaczego C używał tak wielu z nich. Jeśli coś, zasoby dotyczące zrozumienia programów systemowych WIN32 pomogłyby – numerical25

0

To prawie tak, jak powinieneś wypróbować jedną z wielu owijaczy OO. Podobnie jak MFC lub .net.

+0

.Net nie jest opakowaniem Win32. –

+2

Co może .net zrobić, że nie jest na niższym poziomie API – rerun

+1

Jestem głównie programistą C++, ale nawet ja mogę przyznać, że .Net umożliwia niezaprzeczalnie szybszy rozwój i mniej podatny na błędy kod. Nie wspominając już o mniej surowym kodzie do utrzymania. –

0

Interfejs API systemu Windows to zwykły stary język C, stąd wszędzie można używać wskaźników. Powodem, dla którego pytasz Windows o nowy wskaźnik, jest to, że system Windows musi śledzić wszystkie obiekty ... przydziela rzeczy i informuje wskaźnik (lub czasami tylko numeryczny identyfikator), abyś mógł z nimi pracować.

7

Ponieważ Win32 Api są napisane na zwykłym C, a nie C++. Tak więc każdy program w prawie dowolnym języku może nawiązać połączenie z tym API.

Co więcej, nie ma prostego mechanizmu do używania obiektów w różnych modułach i różnych językach. To znaczy. nie można eksportować klasy C++ do Pythona. Oczywiście istnieją technologie takie jak OLE/COM, ale nadal są napisane na zwykłym C. Są one nieco skomplikowane w użyciu.

Z drugiej strony - wywołania zwykłych funkcji C są ustandaryzowane. Możesz więc wywoływać procedury z biblioteki DLL lub statycznej biblioteki w dowolnym języku.

0
  • Posiadanie funkcji C jako interfejsu API pozwala programistom C i C++ go używać.
  • Interfejsy API systemu Windows znacznie się różnią - C słynęło w tamtych czasach.

Wszystkie HWND, uchwyt HDC to tylko słabe próba wykonania ściśnięta przedmiotów-jak rodzaje danych (przy użyciu struct). C FAQ ma pytanie na ten temat ->http://c-faq.com/struct/oop.html.

+2

Funkcje języka C umożliwiają większości języków, w tym Python, Haskell i C#, wywoływanie Win32. :) – Macke

+0

+1 za wzmiankę o innych langach, C ma taką ogólność, jeśli chodzi o ABI :) – legends2k

Powiązane problemy