26

Tôi đang xem xét chữ ký của toán tử mới. Đó là:toán tử mới để cấp phát bộ nhớ trên heap

void* operator new (std::size_t size) throw (std::bad_alloc); 

Nhưng khi sử dụng toán tử này, chúng tôi không bao giờ sử dụng dàn diễn viên. tức là

int *arr = new int; 

Vì vậy, làm thế nào để C++ chuyển đổi một con trỏ kiểu void* để int* trong trường hợp này. Bởi vì, ngay cả malloc trả lại một void* và chúng tôi cần sử dụng một cách rõ ràng một diễn viên.

Trả lời

39

Có sự khác biệt rất tinh tế trong C++ giữa operator new và toán tử new. (Đọc lại lần nữa ... thứ tự quan trọng!)

Chức năng operator new là tương tự C++ của hàm C malloc của C. Đó là một bộ cấp phát bộ nhớ thô có trách nhiệm chỉ để tạo ra một khối bộ nhớ để xây dựng các đối tượng. Nó không gọi bất kỳ nhà xây dựng nào, bởi vì đó không phải là công việc của nó. Thông thường, bạn sẽ không thấy operator new được sử dụng trực tiếp trong mã C++; có vẻ hơi lạ. Ví dụ:

void* memory = operator new(137); // Allocate at least 137 bytes 

Toán tử new là từ khóa có trách nhiệm cấp phát bộ nhớ cho đối tượng và gọi hàm tạo của nó. Đây là những gì thường gặp nhất trong mã C++. Khi bạn viết

int* myInt = new int; 

Bạn đang sử dụng toán tử mới để cấp số nguyên mới. Bên trong, nhà điều hành new hoạt động gần như thế này:

  1. Phân bổ bộ nhớ để giữ đối tượng được yêu cầu bằng cách sử dụng operator new.
  2. Gọi hàm tạo đối tượng, nếu có. Nếu điều này ném một ngoại lệ, hãy giải phóng bộ nhớ ở trên với operator delete, sau đó truyền bá ngoại lệ.
  3. Trả lại con trỏ cho đối tượng mới được xây dựng.

Vì toán tử newoperator new riêng biệt, có thể sử dụng từ khóa new để tạo đối tượng mà không thực sự phân bổ bộ nhớ. Ví dụ, vị trí nổi tiếng mới cho phép bạn xây dựng một đối tượng tại một địa chỉ bộ nhớ tùy ý trong bộ nhớ do người dùng cung cấp. Ví dụ:

T* memory = (T*) malloc(sizeof(T)); // Allocate a raw buffer 
new (memory) T(); // Construct a new T in the buffer pointed at by 'memory.' 

Quá tải toán tử new bằng cách định nghĩa một tùy chỉnh operator new chức năng cho phép bạn sử dụng new theo cách này; bạn chỉ định cách phân bổ xảy ra, và trình biên dịch C++ sẽ nối nó vào toán tử new.

Trong trường hợp bạn tò mò, từ khóa delete hoạt động theo cùng một cách.Có một chức năng deallocation gọi là operator delete chịu trách nhiệm xử lý bộ nhớ, và cũng là một toán tử delete chịu trách nhiệm cho việc gọi các trình phá hủy đối tượng và giải phóng bộ nhớ. Tuy nhiên, operator newoperator delete có thể được sử dụng bên ngoài các ngữ cảnh này thay cho ví dụ của mallocfree của C.

+0

Bước hai nên được "Gọi constructor đối tượng, nếu có. Nếu điều này ném * bất kỳ ngoại lệ *, miễn phí bộ nhớ trên và tuyên truyền ngoại lệ." – GManNickG

+0

@ GMan- Cảm ơn vì đã phát hiện ra điều đó! Lỗi của tôi. Tôi sẽ sửa chữa nó. – templatetypedef

+0

Giải thích thực sự tuyệt vời. Cảm ơn rất nhiều !!! –

4

Bạn nhầm lẫn new biểu thức với hàm operator new(). Khi trước đây được biên dịch trình biên dịch trong số các công cụ khác tạo ra một cuộc gọi đến chức năng operator new() và vượt qua kích thước đủ để giữ loại được đề cập trong biểu thức new và sau đó một con trỏ của loại đó được trả về.

+0

Đối với bất kỳ ai bị bỏ phiếu - có gì sai với câu trả lời này? Nó có vẻ hoàn toàn chính xác. – templatetypedef

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