2012-02-25 12 views
19

thể trùng lặp:
Deleting pointers in a vectorKhông std :: vector gọi destructor của con trỏ đến các đối tượng?

tôi biết khi nào một std::vector là destructed, nó sẽ gọi destructor của từng hạng mục của nó. Nó có gọi là destructor của con trỏ cho các đối tượng không?

vector<myclass*> stuff; 

Khi công cụ bị phá hủy, các đối tượng riêng lẻ được chỉ ra bởi con trỏ bên trong nội dung có bị phá hủy không?

+0

Kiểm tra [boost :: ptr_vector ] (http://www.boost.org/doc/libs/1_49_0/libs/ptr_container/doc/ptr_vector.html) –

Trả lời

30

số

như thế nào std::vector phải biết làm thế nào để tiêu diệt các nhọn để phản đối? Nó có nên sử dụng delete không? delete[]? free? Một số chức năng khác? Làm thế nào là nó phải biết các đối tượng chỉ đến thực sự được phân bổ động hoặc đó là một chủ sở hữu thực sự và chịu trách nhiệm phá hủy chúng?

Nếu số std::vector là Chủ sở hữu thực sự của đối tượng được chỉ định, hãy sử dụng std::unique_ptr, có khả năng có dấu tùy chỉnh để xử lý việc dọn dẹp đối tượng.

+1

Nếu 'std :: vector' sẽ có constructor có chức năng hủy diệt cho các yếu tố sẽ là dandy. Nó sẽ hữu ích cho di sản hoặc C API. Nhưng dù sao thì cách tốt hơn để làm mọi thứ là gói loại tài nguyên này với một lớp RAII. – wilhelmtell

+1

@wilhelmtell bạn có thể viết một phân bổ tùy chỉnh cho điều đó :) Hoặc cung cấp cho 'unique_ptr' một chức năng deleter tùy chỉnh. –

+0

@SethCarnegie vâng, nó đã đánh tôi vài giây sau khi đăng bình luận. xảy ra với tôi mọi lúc, nói trước khi suy nghĩ. : -S – wilhelmtell

5

Không; nếu bạn lưu một con trỏ đến một đối tượng tự động thì sao?

vector<T*> v; 
T tinst; 
v.push_back(&tinst); 

Nếu vector gọi destructor của các đối tượng con trỏ trỏ đến, đối tượng tự động sẽ được destructed hai lần - một lần khi nó đã đi ra khỏi phạm vi, và một lần khi vector đã đi ra khỏi phạm vi. Ngoài ra, điều gì sẽ xảy ra nếu chúng không được xử lý với delete? Không có cách nào nó có thể hành xử một cách thích hợp trong mọi tình huống.

Nếu đối tượng của bạn được phân bổ động, bạn phải lặp lại thủ công vectơ và delete mỗi con trỏ nếu nó được cấp phát với new. Ngoài ra, bạn có thể tạo ra một vector của con trỏ thông minh mà sẽ deallocate các đối tượng được trỏ đến bởi con trỏ:

vector<shared_ptr<T>> v; 
v.push_back(new T); 
+0

Hm. Tôi nghĩ từ thứ hai, "bởi vì", là gây hiểu nhầm. Các onus để biện minh cho không xóa pointees không phải là trên vector; thay vào đó, OP phải giải thích lý do tại sao một container * nên * xử lý các yếu tố con trỏ gõ khác nhau. Khi nó đứng, câu trả lời có thể đơn giản, "Không." –

+1

@KerrekSB gỡ bỏ sau đó :) –

15

Như bạn nói đúng mình, vector không hủy cuộc gọi cho các yếu tố của nó. Vì vậy, trong ví dụ của bạn, vector thực hiện gọi là "trình phá hủy các con trỏ". Tuy nhiên, bạn phải ghi nhớ rằng các kiểu con trỏ không có destructors. Chỉ có các loại lớp mới có thể có các trình phá hủy. Và con trỏ không phải là lớp. Vì vậy, nó là chính xác hơn để nói rằng std::vector áp dụng cú pháp cuộc gọi giả-destructor cho các đối tượng con trỏ được lưu trữ trong vectơ. Đối với các loại con trỏ mà kết quả là không hoạt động, tức là không có gì.

Điều này cũng trả lời phần thứ hai của câu hỏi của bạn: liệu các đối tượng myclass được trỏ bởi con trỏ có bị phá hủy hay không. Không, họ không bị phá hủy. Ngoài ra, có vẻ như bạn bằng cách nào đó tin rằng "gọi destructors trên con trỏ" (phần đầu tiên của câu hỏi của bạn) là cùng một điều như "phá hủy các đối tượng nhọn" (phần thứ hai của câu hỏi của bạn). Trong thực tế đây là hai thứ hoàn toàn không liên quan khác nhau.

Để tạo liên kết từ danh sách cũ đến sau, tức làđể làm cho vectơ phá hủy các đối tượng nhọn, bạn cần phải xây dựng vectơ của bạn từ một số loại "con trỏ thông minh", trái ngược với con trỏ thô thông thường myclass *. Các vector sẽ tự động gọi destructors của "con trỏ thông minh" và những destructors, lần lượt, sẽ phá hủy các đối tượng nhọn. "Liên kết" này chỉ có thể được thực hiện một cách rõ ràng, bên trong trình phá hủy "con trỏ thông minh", đó là lý do tại sao con trỏ thô thông thường không thể giúp bạn ở đây.

+0

Trên thực tế nếu bạn muốn được chính xác, 'std :: vector' không phá hủy bất cứ điều gì, cấp phát hiện –

+0

+1 Haha, rất tốt, tại chỗ. –

+0

Đây phải là câu trả lời được chấp nhận vì nó cho thấy lý do tại sao con trỏ không có trường hợp đặc biệt. –