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ì?
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ì?
Câu trả lời:
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.
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);
}
}
Xử lý 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 đó.
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 new
và kết quả của một new
biể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 gcnew
biể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.
Đ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.
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ì đó.
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