2012-02-28 35 views
12

Câu hỏi của tôi là đơn giản, nhưng tôi đã không thể tìm thấy câu hỏi ở bất cứ đâu.Liệu destructor có được gọi tự động

Nếu tôi có một lớp học như vậy

class A { 
    vector<int> data; 
} 

Khi một thể hiện của A bị phá hủy sẽ data cũng bị phá hủy đúng cách, hay tôi nên viết một destructor cho A mà các cuộc gọi data 's destructor? Về cơ bản tôi lo lắng về việc liệu bộ nhớ động của vector sẽ không được giải phóng khi một cá thể của A bị phá hủy. Tôi nghi ngờ câu trả lời là data được giải phóng đúng cách, nhưng tôi không muốn tìm ra tôi là sai đường khó.

Hơn nữa, nếu A là cấu trúc thì hàm hủy cho số data được gọi khi phiên bản địa phương của A rơi ra khỏi phạm vi?

+2

Bạn đang thiếu một dấu chấm phẩy sau khi khai báo 'lớp A' (đây thực sự không phải là một tuyên bố vì nó thiếu ... oh well). –

Trả lời

14

Có, data sẽ tự động bị hủy, bạn không cần phải làm gì để đạt được điều đó. vector sẽ xử lý việc dọn dẹp bộ nhớ động được phân bổ bởi nó. Destructor của vector sẽ được gọi tự động khi một thể hiện của A bị phá hủy.

Không có sự khác biệt về hành vi bất kể Aclass hoặc struct.

+14

+1 Chỉ cần rõ ràng, "vectơ sẽ xử lý việc dọn dẹp bộ nhớ động được cấp phát * bởi * nó", không * với * nó. Nếu bạn lưu trữ các đối tượng được phân bổ động trong một vectơ, đó là trách nhiệm của bạn để 'xóa' chúng cho phù hợp. – netcoder

+0

@netcoder tìm thấy nhận xét của bạn một chút gây hiểu lầm. Bạn có thể lưu trữ trong một vector ** con trỏ tới các đối tượng được phân bổ động ** nhưng tôi không nghĩ rằng bạn có thể lưu trữ các "đối tượng" được tự động phân bổ trong một vectơ. Nếu bạn khai báo một vector trong đó ClassA là một tên lớp, thì vectơ sẽ xử lý việc phá hủy các đối tượng ClassA mà nó giữ.Tất nhiên, nếu đối tượng ClassA của bạn giữ con trỏ đến các đối tượng khác thì trách nhiệm của ClassA là xóa **, ** KHÔNG phải là trách nhiệm của vector **, nhưng đó là một câu chuyện khác. –

2

Không cần, trình phá hủy của thành viên dữ liệu luôn được gọi.

Một destructor rõ ràng là hữu ích cẩm nang quản lý bộ nhớ

struct a{ 
    int* ip; 
    a() 
    : ip(new int(5)) 
    { } 

    ~a() { delete ip; } 
}; 

Điều đó nói rằng, bạn thường nên nói container sử dụng RAII (như gợi ý thông minh) để cá nhân tôi hiếm khi viết dtors có ngày.

Và ngoại lệ cho điều đó là khai báo một lớp cơ sở dtor là ảo.

struct base { 
    virtual ~base() {} 
}; 
struct child : public base { 
    //base and child destructor automatically called 
} 
+0

+1 để tôn trọng các nguyên tắc RAII tốt. Sự cần thiết phải tự viết các destructors nên nhận được ít hơn và ít hơn khi mọi người đang mã hóa C++ theo cách Stroustrup, Sutter, Meyers, và các nhà tư tưởng C++ hiện đại khác có ý định chúng ta viết nó. – stinky472

1

Trình hủy mặc định được tạo tự động bởi trình biên dịch nếu bạn không tự xác định. Nói chung, bạn không cần phải tạo ra destructor của riêng bạn trừ khi bạn có các thành viên dữ liệu con trỏ "sở hữu" bộ nhớ mà chúng trỏ tới, và/hoặc bạn đang thiết kế lớp của bạn để được bắt đầu bởi các lớp khác, tại thời điểm bạn muốn ít nhất phải khai báo một hàm hủy rỗng virtual trống.

Trong tất cả các trường hợp, cả với trình hủy của riêng bạn, cũng như trình phá hủy được tạo bởi trình biên dịch mặc định, tất cả các trình phá hủy cho các thành viên dữ liệu không tĩnh cũng như bất kỳ lớp cơ sở nào của lớp hiện tại được gọi vào cuối destructor và trước khi hàm destructor tự trả về.

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