2013-11-04 26 views
6

Trong khi khai quật tại C++ Dự án, tôi gặp phải một cách sử dụng kỳ lạ của new điều hành C++ 's:Strange C++ sử dụng toán tử new

int arr[5]; 
ClassA* a = new(arr) ClassA(); 

Bạn có vui lòng giúp tôi hiểu cú pháp này?

+5

google "vị trí mới" hoặc xem câu hỏi này: http://stackoverflow.com/questions/222557/what-uses-are-there-for -placement-new – Kos

+0

@Askyane Tôi đã bao gồm một bản tóm tắt ngắn gọn và một liên kết cho perusal của bạn – GMasucci

Trả lời

2

Đó là cú pháp mới của vị trí - nó cho phép bạn xây dựng một đối tượng tại vị trí được chỉ định trong bộ nhớ. Hãy xem xét việc sử dụng "bình thường" mới:

X *p = new X; 
... 
delete p; 

Bạn có thể đạt được hiệu quả tương tự bằng cách thực hiện:

#include <new> 

... 

void *buffer = ::operator new(sizeof(X)); 
X *p = new (buffer) X; 
... 
p->~X(); 
::operator delete(buffer); 

Sau đó phân bổ đủ bộ nhớ để tổ chức một X (không xây dựng một X trong nó), sau đó xây dựng một cách rõ ràng X trong bộ nhớ được cấp phát. Sau đó, nó phá hủy rõ ràng X nó đã tạo và sau đó deallocates bộ nhớ có chứa nó.

Xem thêm C++ Hỏi đáp: http://www.parashift.com/c++-faq/placement-new.html

2

Nhà điều hành new() có thể mất một size (kích thước tính bằng byte) nothrow_value (trả về một con trỏ null thay vì một ngoại lệ bad_alloc) hoặc pointer (xây dựng các đối tượng trong bộ nhớ đã được phân bổ được chỉ bởi con trỏ này) đối số, và trong cách sử dụng bạn mô tả nó đang tạo ra một đối tượng mới tại vị trí bộ nhớ được trỏ đến bởi arr. Đối với một hướng dẫn phong nha về nó, tôi sẽ xem xét this link.

Trong trường hợp bạn trích dẫn nó được sử dụng con trỏ cho arr để tạo ra ví dụ mới của ClassA trong.

2

Cú pháp này được gọi là cú pháp placement new. Nó thường được sử dụng để xây dựng một đối tượng trên một bộ đệm được cấp phát trước. Điều này rất hữu ích khi xây dựng một pool bộ nhớ, một bộ thu gom rác hoặc đơn giản khi hiệu năng và ngoại lệ an toàn là tối quan trọng (không có nguy cơ phân bổ thất bại vì bộ nhớ đã được cấp phát và xây dựng một đối tượng trên bộ đệm được cấp phát trước mất ít thời gian hơn) .

char *buf = new char[sizeof(string)]; // pre-allocated buffer 
string *s1 = new (buf) string("test1"); // placement new 
string *s2 = new string("test2"); //ordinary new 

Khi nói đến deallocation, không có placement delete tự động thực hiện phép thuật. Bạn không nên deallocate mọi đối tượng đang sử dụng bộ nhớ đệm. Thay vào đó, bạn nên hủy từng đối tượng theo cách thủ công, sau đó chỉ xóa [] chỉ bộ đệm gốc

+2

Tôi nghĩ rằng bạn có nghĩa là hủy từng đối tượng theo cách thủ công và sau đó xóa bộ đệm gốc, chứ không phải theo cách khác. –

+1

@StuartGolodetz xin lỗi vì sai lầm ngu ngốc đó. sửa nó – jester