Xử lý trong C ++ là gì?


97

Tôi đã được nói rằng một xử lý là một loại con trỏ, nhưng không phải, và nó cho phép bạn giữ một tham chiếu đến một đối tượng, thay vì chính đối tượng. Giải thích tỉ mỉ hơn là gì?



2
Nhìn vào mẫu Chuỗi trách nhiệm, bạn sẽ biết rằng "Xử lý" về cơ bản là một nút và "Trình xử lý" là một tập hợp nhỏ của chúng. Các "ma thuật" xuất phát từ đệ quy

Câu trả lời:


100

Xử lý có thể là bất kỳ thứ gì từ một chỉ mục số nguyên đến một con trỏ đến một tài nguyên trong không gian hạt nhân. Ý tưởng là chúng cung cấp sự trừu tượng của một tài nguyên, vì vậy bạn không cần biết nhiều về chính tài nguyên đó để sử dụng nó.

Ví dụ: HWND trong Win32 API là một xử lý cho một Cửa sổ. Tự nó nó vô dụng: bạn không thể thu thập bất kỳ thông tin nào từ nó. Nhưng hãy chuyển nó vào các hàm API phù hợp và bạn có thể thực hiện vô số thủ thuật khác nhau với nó. Bên trong, bạn có thể coi HWND chỉ là một chỉ mục trong bảng cửa sổ của GUI (có thể không nhất thiết là cách nó được triển khai, nhưng nó có ý nghĩa).

CHỈNH SỬA: Không chắc chắn 100% những gì cụ thể bạn đã hỏi trong câu hỏi của mình. Điều này chủ yếu nói về C / C ++ thuần túy.


13
Một Xử lý có thể hữu ích để lưu các trạng thái (trong số các trạng thái khác). Nếu u có dữ liệu trong một cấu trúc như một vector std ::. Đối tượng của bạn có thể ở các vị trí bộ nhớ khác nhau vào những thời điểm khác nhau trong quá trình thực thi một chương trình, có nghĩa là con trỏ của bạn tới bộ nhớ đó sẽ thay đổi giá trị. Với một tay cầm, nó không bao giờ thay đổi, nó luôn tham chiếu đến đối tượng của bạn. Hãy tưởng tượng lưu trạng thái của một chương trình (như trong một trò chơi) - bạn sẽ không lưu vị trí con trỏ vào dữ liệu và sau đó nhập dữ liệu lại và cố gắng lấy địa chỉ đó trong bộ nhớ. Tuy nhiên, bạn có thể lưu một Xử lý với dữ liệu của mình và nhập dữ liệu và xử lý.
SinisterRainbow

Có thể chuyển đổi HANDLE thành một tệp tương đương trong Linux không? Tôi phải di chuyển một chương trình sử dụng HANDLE từ Windows sang Linux.
Cornel Verster

1
Đó là câu trả lời chính xác, rằng chúng có thể là bất kỳ thứ gì và mã sử dụng chúng xác định loại tay cầm. Tôi đã cố gắng tạo ra một phiên bản ngắn gọn hơn cho câu trả lời tương tự của riêng mình, không thể giúp ích cho chính mình, cho hậu thế. @CornelVerster - Chúng giống nhau trong linux. Ý tôi là, không phải hệ điều hành xử lý mà là khái niệm. Vì vậy, nó phụ thuộc vào cách xử lý khi di chuyển của nó, hoặc thậm chí cần phải di chuyển.
dyasta

@Matthew Iselin: trong bất kỳ tài liệu API nào, họ có xác định thứ đó là trình xử lý hay không thì chúng ta nên biết để chuyển chúng cho các hàm, nếu không làm thế nào chúng ta có thể biết trình xử lý là gì trong tài liệu API
Amin Khormaei

51

Xử lý là một con trỏ hoặc chỉ mục không có kiểu hiển thị nào được gắn vào nó. Thông thường bạn sẽ thấy một cái gì đó như:

 typedef void* HANDLE;
 HANDLE myHandleToSomething = CreateSomething();

Vì vậy, trong mã của bạn, bạn chỉ cần chuyển HANDLE xung quanh như một giá trị không rõ ràng.

Trong mã sử dụng đối tượng, nó truyền con trỏ đến một kiểu cấu trúc thực và sử dụng nó:

 int doSomething(HANDLE s, int a, int b) {
     Something* something = reinterpret_cast<Something*>(s);
     return something->doit(a, b);
 }

Hoặc nó sử dụng nó làm chỉ mục cho một mảng / vectơ:

 int doSomething(HANDLE s, int a, int b) {
     int index = (int)s;
     try {
         Something& something = vecSomething[index];
         return something.doit(a, b);
     } catch (boundscheck& e) {
         throw SomethingException(INVALID_HANDLE);
     }
 }

29

Xử lý một loại con trỏ trong đó nó thường là một cách tham chiếu đến một số thực thể.

Sẽ chính xác hơn nếu nói rằng con trỏ là một loại tay cầm, nhưng không phải tất cả các chốt đều là con trỏ.

Ví dụ, một xử lý cũng có thể là một số chỉ mục trong một bảng trong bộ nhớ, tương ứng với một mục nhập mà bản thân nó chứa một con trỏ đến một số đối tượng.

Điều quan trọng là khi bạn có một "tay cầm", bạn không biết cũng như không quan tâm đến việc làm thế nào mà tay cầm đó thực sự xác định được thứ mà nó xác định, tất cả những gì bạn cần biết là nó làm được.

Cũng cần phải hiển nhiên rằng không có câu trả lời duy nhất cho "chính xác là một xử lý", bởi vì các xử lý đối với những thứ khác nhau, ngay cả trong cùng một hệ thống, có thể được thực hiện theo những cách khác nhau "ẩn". Nhưng bạn không cần phải quan tâm đến những khác biệt đó.


6

Trong C ++ / CLI, một xử lý là một con trỏ đến một đối tượng nằm trên GC heap. Tạo một đối tượng trên đống C ++ (không được quản lý) được thực hiện bằng cách sử dụng newvà kết quả của một newbiểu thức là một con trỏ "bình thường". Một đối tượng được quản lý được phân bổ trên GC (được quản lý) với một gcnewbiểu thức. Kết quả sẽ là một xử lý. Bạn không thể thực hiện số học con trỏ trên các chốt. Bạn không có tay cầm miễn phí. GC sẽ chăm sóc họ. Ngoài ra, GC có thể tự do di dời các đối tượng trên heap được quản lý và cập nhật các chốt điều khiển để trỏ đến các vị trí mới trong khi chương trình đang chạy.


5

Điều này xuất hiện trong ngữ cảnh của Handle-Body-Idiom , còn được gọi là thành ngữ Pimpl. Nó cho phép người ta giữ nguyên ABI (giao diện nhị phân) của một thư viện, bằng cách giữ dữ liệu thực tế vào một đối tượng lớp khác, đối tượng này chỉ được tham chiếu bởi một con trỏ được giữ trong một đối tượng "xử lý", bao gồm các hàm ủy nhiệm cho lớp đó " Thân hình".

Nó cũng hữu ích để bật thời gian không đổi và hoán đổi an toàn ngoại lệ của hai đối tượng. Đối với điều này, chỉ cần con trỏ trỏ đến đối tượng body phải được hoán đổi.


2

Tay cầm là bất cứ thứ gì bạn muốn.

Ô điều khiển có thể là một số nguyên không dấu được sử dụng trong một số bảng tra cứu.

Một xử lý có thể là một con trỏ đến hoặc vào một tập dữ liệu lớn hơn.

Nó phụ thuộc vào cách mã sử dụng xử lý hoạt động. Điều đó xác định loại tay cầm.

Lý do thuật ngữ ' tay cầm ' được sử dụng là điều quan trọng. Điều đó chỉ ra chúng như một loại đối tượng nhận dạng hoặc truy cập. Có nghĩa là, đối với lập trình viên, chúng đại diện cho một 'chìa khóa' hoặc quyền truy cập vào một thứ gì đó.


2

HANDLE hnd; giống như void * ptr;

HANDLE là một typedef được định nghĩa trong tệp winnt.h trong Visual Studio (Windows):

typedef void *HANDLE;

Đọc thêm về HANDLE


1
Điều đó chỉ áp dụng cho Windows và chỉ một trong nhiều loại tay cầm được sử dụng thông qua kiến ​​trúc Windows. Tuy nhiên, đó những gì sẽ được gọi là 'một trình xử lý cấp ứng dụng Windows bình thường'.
dyasta
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.