2009-08-22 39 views
12

Tôi có một lớp cơ sở A và một nguồn gốc lớp B:Tại sao destructor của tôi không bao giờ được gọi?

class A 
{ 
public: 
    virtual f(); 
}; 

class B : public A 
{ 
public: 
    B() 
    { 
     p = new char [100]; 
    } 
    ~B() 
    { 
     delete [] p; 
    } 
    f(); 
private: 
    char *p; 
}; 

Đối với bất kỳ lý do destructor không bao giờ được gọi là - tại sao? Tôi không hiểu điều này.

+1

Mặc dù mọi người đã tìm ra vấn đề là gì (Vì đây là câu hỏi thường gặp trong C++), tôi vẫn đề nghị bạn nên hiển thị mã như thế nào bạn sử dụng lớp B. (Nếu bạn sử dụng nó theo cách này: B * p = new B(); xóa p; và destructor không bao giờ được gọi, sau đó nó phải là vấn đề hoàn toàn khác nhau.) –

Trả lời

35

Lớp cơ sở của bạn cần có trình phá hủy ảo. Nếu không thì hàm hủy của lớp dẫn xuất sẽ không được gọi, nếu chỉ có một con trỏ kiểu A * được sử dụng.

Thêm

virtual ~A() {}; 

đến lớp A.

+0

là có bất kỳ lý do không sử dụng destructor ảo này trong lớp học chính? – sluki

7

Lớp A phải có trình phá hủy ảo. Nếu không có điều đó, các trình phá hủy lớp dẫn xuất sẽ không được gọi.

+2

Sẽ không được gọi là iff destructor được gọi là thông qua một con trỏ đến A. –

3

thử điều này:

class A 
{ 
public: 
    virtual ~A() {} 
    virtual f(); 
}; 

class B : public A 
{ 
public: 
    B() 
    { 
     p = new char [100]; 
    } 
    virtual ~B() // virtual keywork optional but occasionally helpful for self documentation. 
    { 
     delete [] p; 
    } 
    f(); 
private: 
    char *p; 
}; 
3

Nếu biến của bạn là loại A nó không có một destructor ảo và vì vậy nó đã giành' t xem loại thời gian thực tế của đối tượng để xác định nó cần gọi cho người dẫn đường

A dd một destructor rỗng để A

virtual ~ A() {}

và điều đó nên khắc phục.

Nói chung, bạn cần thực hiện việc này trên bất kỳ lớp nào có thể được sử dụng làm lớp cơ sở.

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