2010-02-25 31 views
8

Đây có thể là một câu hỏi ngớ ngẩn đối với một số bạn và có thể tôi đã đặt câu hỏi này sai, bởi vì tôi mới đến với C++. Nhưng tôi nhận thấy khi làm việc trong rất nhiều ứng dụng win32, bạn sử dụng rất nhiều tài nguyên là con trỏ. Tại sao bạn phải luôn luôn có được một con trỏ đối tượng? tại sao không bắt đầu một thể hiện mới của lớp. và nói về điều đó, tôi nhận thấy trong hầu hết các trường hợp, bạn không bao giờ khởi tạo đối tượng mới, nhưng luôn gọi các phương thức trả về con trỏ đó. Điều gì nếu con trỏ đó đang được sử dụng ở một nơi khác. bạn không thể làm hỏng điều gì đó nếu bạn thay đổi con trỏ đó và nó đang được sử dụng ở một nơi khác.ứng dụng win32 không hướng đối tượng và tại sao có quá nhiều con trỏ?

Trả lời

24

API Windows được thiết kế cho C, mà vẫn là ngôn ngữ được sử dụng nhiều nhất cho lập trình hệ thống; C API là tiêu chuẩn thực tế cho các API hệ thống và cho hầu hết các ngôn ngữ khác có và có một số cách gọi các hàm C bên ngoài, vì vậy việc viết C API giúp tương thích với các ngôn ngữ khác.

API C chỉ cần một ABI đơn giản, bao gồm gần như chỉ định nghĩa cho quy ước gọi để sử dụng cho các hàm (và một cái gì đó về bố cục cấu trúc). C++ và các ngôn ngữ hướng đối tượng khác, ngược lại, yêu cầu ABI phức tạp, phải xác định cách đối tượng được đặt trong bộ nhớ, cách xử lý thừa kế, cách bố trí vtable, cách truyền các ngoại lệ, nơi đặt dữ liệu RTTI, ... Hơn nữa không phải tất cả các ngôn ngữ đều hướng đối tượng và sử dụng API cho C++ với các ngôn ngữ không hướng đối tượng khác có thể là một nỗi đau thực sự (nếu bạn đã từng sử dụng COM từ C bạn biết ý tôi là gì). Ngoài ra, khi Windows được thiết kế ban đầu thì C++ không được phổ biến rộng rãi trên PC, và C cũng không được sử dụng vì vậy nhiều: thực tế, một phần lớn của Windows 3.11 và nhiều ứng dụng vẫn được viết trong assembly , vì bộ nhớ và các ràng buộc CPU ở thời đại rất chặt chẽ; các trình biên dịch cũng kém thông minh hơn bây giờ, đặc biệt là các trình soạn thảo C++. Trên những máy có lắp ráp bằng tay thường là giải pháp duy nhất, chi phí C++ thực sự không thể chấp nhận được.

Đối với điều con trỏ: API Windows sử dụng hầu như luôn luôn xử lý, tức là con trỏ đục để có thể thay đổi bản chất cơ bản của mọi tài nguyên mà không ảnh hưởng đến các ứng dụng hiện có và dừng ứng dụng. Nó không quan trọng nếu cấu trúc được sử dụng bởi người quản lý cửa sổ để đại diện cho một cửa sổ nội bộ được thay đổi: tất cả các ứng dụng sử dụng chỉ đơn giản là một HWND, mà luôn luôn là kích thước của một con trỏ. Bạn có thể nghĩ đây là một dạng thành ngữ PIMPL. Tuy nhiên, Windows là một cách nào đó hướng đối tượng (xem ví dụ toàn bộ khái niệm "cửa sổ lớp", hoặc, ở một mức độ sâu hơn, làm việc bên trong của hạt nhân NT, mà là rất nhiều dựa trên "đối tượng" khái niệm), tuy nhiên các API cơ bản nhất của nó, là các hàm C đơn giản, bằng cách nào đó ẩn bản chất OO này. Shell, ở phía bên kia, được thiết kế nhiều năm sau, được viết chủ yếu bằng C++ và nó cung cấp một giao diện COM thực sự hướng đối tượng. Một điều thú vị là bạn có thể thấy trong COM tất cả các sự cân bằng mà bạn phải đối mặt trong việc xây dựng một giao diện hướng đối tượng nhưng vẫn là C++, kết quả khá phức tạp, ở một số khía cạnh xấu xí và không thực sự dễ sử dụng bất kỳ ngôn ngữ nào. Các API Windows, thay vào đó, là các hàm đơn giản thường dễ gọi hơn.

Nếu bạn quan tâm đến một hệ thống dựa trên API C++, bạn có thể xem Haiku; cá nhân, đây là một trong những khía cạnh vì tôi khá quan tâm đến dự án đó.

Nhân tiện, nếu bạn định lập trình Win32 chỉ với các API, bạn nên có được một cuốn sách tốt để làm quen với các "đặc điểm" này và các thành ngữ Win32 khác. Hai cái nổi tiếng là Rector-NewcomerPetzhold.

+0

cảm ơn. từ tất cả các câu trả lời. nó có ý nghĩa hơn bây giờ. – numerical25

+0

Giải thích tuyệt vời. Một câu hỏi mặc dù: nếu Win32 thực sự là đối tượng định hướng, tại sao nó rất khó để có được một con trỏ dụ trong một chức năng WndProc (cho là trái tim của toàn bộ API)? (xem http://www.codeguru.com/forum/printthread.php?t=234315) –

+0

@Jared: bản chất hướng đối tượng nhiều hơn hoặc ít hơn của API Win32 là một khái niệm không có gì để làm với hệ thống kiểu C++. Các lớp cửa sổ là một khái niệm về trình quản lý cửa sổ, không phải của ngôn ngữ cụ thể mà bạn đang sử dụng để truy cập các tính năng WM. Bạn có thể tạo một sự tương ứng giữa các lớp/đối tượng C++ với các lớp/trường hợp cửa sổ, nhưng theo nguyên tắc chúng là những thứ hoàn toàn không liên quan. –

1

Có lẽ vì API Win32 là "cũ" hơn so với lập trình hướng đối tượng chính thống, nó không phải là API C++ ở lõi của nó.

5

Win32 được thiết kế để hoạt động với ngôn ngữ C chứ không phải C++.
Đó là lý do tại sao bạn sẽ thấy các loại trả lại của số BOOL được xác định thay vì bool chẳng hạn.
bool dành riêng cho C++ và không tồn tại trong C.

Đối với trình bao bọc hướng đối tượng của Microsoft là Win32 xem MFC.

Một khung công tác mới hơn từ Microsoft kể từ đó là .Net Framework.
Khuôn khổ .Net dựa trên mã được quản lý và không chạy tự nhiên. Cách hiện đại nhất để lập trình GUI trên Windows là WPF hoặc thậm chí là Silverlight.

Cách hiện đại nhất để làm chương trình GUI không được quản lý vẫn đang sử dụng MFC, mặc dù một số người vẫn thích sử dụng Win32 thẳng.

Lưu ý rằng việc làm việc với con trỏ không dành riêng cho C, nó vẫn rất phổ biến trong C++.

+2

MFC quá cũ và được thiết kế kém, tôi sẽ không khuyên bạn sử dụng nó ... – dimsuz

+1

@dpimka: Người đăng tải yêu cầu cụ thể về Win32. MFC không xa Win32 và đáng nói đến trong bối cảnh đó. –

+3

MFC vẫn là phương thức OO chính thức để thực hiện Windows trong C++, phải không? –

4

Lý do đầu tiên là do các con trỏ đi qua có giá rẻ. Con trỏ là 4 byte trên x86 và 8 byte trên x64. Trong khi cấu trúc hoặc lớp nó trỏ đến có thể chiếm toàn bộ nhiều hơn trong bộ nhớ. Vì vậy, instantiating một lớp học có nghĩa là đặt bộ nhớ mới một lần nữa và một lần nữa. Đây không phải là hiệu quả từ tốc độ và bộ nhớ tiêu thụ POVs.

Cách khác là chuyển tham chiếu đến đối tượng hoặc con trỏ thông minh hoặc cấu trúc tương tự. Nhưng win32 api được thiết kế trong kỷ nguyên C, vì vậy đây là nơi nó được cho đến bây giờ;)

Về tiềm năng gây rối với con trỏ - nó có thể tất nhiên. Nhưng hầu hết thời gian cuộc đời của họ được nêu rõ trong API (nếu không rõ ràng).

-3

Để hiểu các con trỏ bạn có thể muốn đọc the CPlusPlus.com tutorial on pointers.

+0

Tôi hiểu con trỏ. Tôi không hiểu tại sao C lại sử dụng quá nhiều. Nếu bất cứ điều gì, tài nguyên trên sự hiểu biết chương trình hệ thống WIN32 sẽ giúp – numerical25

0

Nó gần giống như bạn nên thử một trong nhiều trình bao bọc OO. Giống như MFC hoặc .net.

+0

. Net không phải là một wrapper Win32. –

+2

Điều gì có thể .net làm điều đó không ở cấp thấp hơn API – rerun

+1

Tôi là nhà phát triển C++ chủ yếu, nhưng thậm chí tôi có thể thừa nhận rằng .Net cho phép phát triển nhanh hơn và ít bị lỗi hơn. Chưa kể đến ít mã thô để duy trì. –

0

API Windows là đồng bằng cũ C, do đó việc sử dụng con trỏ ở mọi nơi. Ngoài ra, lý do bạn yêu cầu Windows cho một con trỏ mới là vì Windows cần theo dõi tất cả các đối tượng ... nó phân bổ mọi thứ và cho bạn biết một con trỏ (hoặc đôi khi chỉ là một ID số) để cho phép bạn làm việc với chúng.

7

Vì Win32 Api được viết trên đồng bằng C, không phải C++. Vì vậy, bất kỳ chương trình nào trên hầu hết mọi ngôn ngữ đều có thể thực hiện cuộc gọi đến các API đó.

Ngoài ra, không có cơ chế đơn giản để sử dụng các đối tượng trên các mô-đun khác nhau và các ngôn ngữ khác nhau. I E. bạn không thể xuất lớp C++ sang python. Tất nhiên, có những kỹ thuật như OLE/COM, nhưng họ vẫn viết trên đồng bằng C. Và họ có chút khó khăn để sử dụng.

Mặt khác, các cuộc gọi đến các hàm thuần C được chuẩn hóa. Vì vậy, bạn có thể gọi các thói quen từ DLL hoặc lib tĩnh trong bất kỳ ngôn ngữ nào.

0
  • Có chức năng C làm API cho phép cả lập trình viên C và C++ sử dụng nó.
  • API Windows trở lại - C nổi tiếng trong những ngày đó.

Tất cả HWND, HANDLE, HDC là một nỗ lực yếu để tạo kiểu dữ liệu giống như kẹp, sử dụng struct). C FAQ có một câu hỏi về điều này ->http://c-faq.com/struct/oop.html.

+2

Có chức năng C cho phép hầu hết các ngôn ngữ, bao gồm Python, Haskell và C#, để gọi Win32. :) – Macke

+0

+1 để đề cập đến các lang khác, C có tính hào phóng khi nói đến ABI :) – legends2k

Các vấn đề liên quan