2012-01-22 42 views
8

Trong C++, nó không được phép gán một con trỏ void * cho bất kỳ con trỏ không tách rời nào mà không có một diễn viên rõ ràng. Điều này đòi hỏi việc sử dụng một static_cast.Tại sao toán tử mới được phép trả về * void cho mọi kiểu con trỏ?

Nhưng những gì là với điều này:

int* iptr = new int; 

Tôi biết rằng điều hành mới được định nghĩa như sau:

void* operator new(size_t); 

như thế nào C++ xử lý này? Tôi biết rằng đây là một câu hỏi cơ bản, nhưng quan trọng. Tôi cũng biết rằng mã cấp thấp phải sử dụng void. Nhưng cách phân công này có thể hợp pháp như thế nào? iptr là một con trỏ tới một int và new trả về một con trỏ để làm mất hiệu lực, sẽ kích hoạt một thông báo như "error: invalid conversion from 'void *' thành 'int *' [-fpermissive]".

+5

Vui lòng đọc: http://stackoverflow.com/questions/2697892/what-is-return-type-of-new-in-c; toán tử biểu thức mới và mới không giống nhau. – Mat

+1

Ngoài ra, điều này: http://stackoverflow.com/questions/2941888/how-operator-new-calls-the-constructor-of-class - Tôi tin rằng cả hai câu trả lời cho câu hỏi của bạn. – Mat

+0

Ngoài ra: cảm ơn bạn Mat! – Peter

Trả lời

19

Bạn đã nhầm lẫn toán tử mới và toán tử mới chức năng. Không sao, mọi người đều làm thế. Chúng hầu như giống nhau, ngoại trừ chúng khác nhau.

Hàm void* operator new(size_t) lấy một khối bộ nhớ thô, không định kiểu từ bất kỳ cây nào mà nó mọc lên và trả về nó cho chương trình.

void* raw_memory = ::operator new(42); 

Đây là chức năng thông thường có tên hơi lạ.

Nhà cung cấp mới không phải là chức năng và không phải là cuộc gọi chức năng. Đó là một cấu trúc ngôn ngữ riêng biệt. Nó lấy bộ nhớ thô (thông thường, một bộ nhớ trả về bởi hàm void* operator new(size_t)) và biến nó thành một đối tượng bằng cách gọi một hàm tạo. Sau đó nó trả về một con trỏ được nhập đúng cho đối tượng mới được tạo ra.

Fish* f = new Fish; 

CẬP NHẬT Đương nhiên, đó cũng là xóa điều hành (trái ngược với các nhà điều hành mới) và void operator delete(void*) function (ngược lại của void* operator new(size_t) chức năng).

Ngoài ra còn có các mới [] nhà điều hành, các xóa [] nhà điều hành, các void* operator new[](size_t) chức năng, và các void operator delete[](void*) chức năng; chúng đối phó với các mảng đối tượng (trái ngược với các đối tượng riêng lẻ).

Ngoài ra còn có các biểu mẫu "vị trí mới" không gọi bất kỳ chức năng nào trong số operator new cho bộ nhớ mới, mà thay vào đó yêu cầu một con trỏ rõ ràng đến bộ nhớ thô. Chúng không có biểu mẫu "xóa" được tích hợp tương ứng. Bạn có thể tự mình cuộn nếu bạn nghiêng, nhưng tôi từ chối nói về bất kỳ điều này trong khi tỉnh táo.

+1

+1 cho "Chúng hầu như giống nhau, ngoại trừ chúng khác nhau." –

+0

Bạn có sử dụng 'delete' trên cả hai? –

+0

@Seth: Không, 'xóa void_ptr;' là hành vi không xác định.Bạn sẽ sử dụng ':: operator delete (void_ptr_from_operator_new);' – Xeo

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