2011-10-21 59 views
5

Tôi đang xem xét một phần của C++ I đến accross khối tuyên bố này:Giải thích về mới() tuyên bố này

static void Vector3DefaultConstructor(Vector3 *self) 
{  
    new(self) Vector3();  
} 

tôi đã không đi qua các nhà điều hành mới đang được sử dụng theo cách này trước đây. Ai đó có thể giải thích tại sao mới được gọi theo cách này?

+0

Như câu trả lời cho biết, đó là vị trí mới. Lý do * thực tế * để viết điều này có thể là cung cấp một giao diện tương thích C cho một thư viện C++, mặc dù các ứng dụng khác (ví dụ như ví dụ về vector std :: của tôi) thông thường hơn một chút. – spraff

Trả lời

3

Điều này được gọi là "vị trí new". Theo mặc định, nó không cấp phát bộ nhớ nhưng thay vì xây dựng đối tượng tại vị trí đã cho (ở đây, self). Nó có thể, tuy nhiên, bị quá tải cho một lớp học.

Xem FAQ để biết thêm thông tin.

Cách đúng để tiêu diệt một đối tượng xây dựng bằng vị trí new là bằng cách gọi destructor trực tiếp:

obj->~Vector3(); 
+0

Vâng, cũng có thể có sự quá tải đối với 'Vector3 *' một cách cụ thể. –

+0

Không phải là nếu bạn sử dụng vị trí mới, bạn sẽ cần phải đảm bảo rằng 'self-> ~ Vector3()' được gọi tại một số điểm. Các đối tượng C++ bình thường có một vòng đời được xác định rõ ràng, khi bạn cần * vị trí mới, đó là vì bạn đang làm điều gì đó lạ mắt mà ngôn ngữ không cung cấp trực tiếp. – spraff

+0

@CatPlusPlus: Điểm tốt, câu trả lời được chỉnh sửa. – NPE

3

Ai đó có thể giải thích tại sao mới được gọi theo cách này?

Tôi có thể cho bạn biết nó làm gì. Nó có hiệu quả gọi hàm tạo trên một phần bộ nhớ tùy ý, do đó xây dựng đối tượng trong phần bộ nhớ đó. Thường xuyên new cả cấp phát bộ nhớ và xây dựng một đối tượng trong bộ nhớ đó; vị trí mới chỉ thực hiện phần sau.

Tại sao mọi người lại viết mã đó? Không có đầu mối. Sẽ có ý nghĩa hơn nếu đối tượng chụp void* thay vì Vector3*. Nhưng trừ khi Vector3::Vector3() là riêng tư, không có lý do gì để ẩn vị trí sử dụng mới bên trong một hàm tĩnh như thế này.

+0

Nó KHÔNG * gọi hàm tạo trên bộ nhớ ** ** tùy ý *. Nó * gọi hàm khởi tạo trên ** bộ nhớ ** đã cho *. – Nawaz

+0

@Nawaz Phần được cho là tùy ý. –

+0

@LucDanton: Có sự khác biệt. [Ai cũng có thể nấu] (http: //en.wikipedia.org/wiki/Ratatouille_ (phim)) không có nghĩa là bất kỳ Tom-Harry-and-Dick nào cũng có thể nấu ăn. – Nawaz

0

Ví dụ thế giới thực: std::vector phân bổ quá đủ bộ nhớ để lưu lượng tải hiện tại của nó, để giảm chi phí trung bình của push_back.

Nếu lưu trữ bộ đệm T*data thì hãy gọi data=new T[capacity] sẽ mặc định xây dựng tải trọng đối tượng T. Rắc rối là, ngữ nghĩa của vector là nó chỉ chứa những gì bạn đã đưa vào nó: chúng tôi có thể preallocate bộ nhớ cho các đối tượng của chúng tôi nhưng những đối tượng không nên tồn tại chưa.

Giải pháp là đặt thành viênthành void* và cấp phát bộ nhớ chưa được nhập cho nó. Bây giờ bất cứ khi nào chúng ta thêm một đối tượng vào thùng chứa, chúng ta cần phải xây dựng nó để đưa đối tượng này vào sự tồn tại và đưa ra ý nghĩa cho con trỏ thô.

template <typename T> 
void vector <T> :: push_back (const T & value) 
{ 
    resize (m_size + 1); 
    // construct a new T in the void buffer. 
    new (reinterpret_cast <T*> (m_data) + m_size) T (value); 
    ++ m_size; 
} 

template <typeame T> 
void vector <T> :: pop_back() 
{ 
    (reinterpret_cast <T*> (m_data) + m_size) -> ~ T(); 
    -- size; 
} 
Các vấn đề liên quan