2013-03-12 43 views
5

Định nghĩa của some_class là:Hành vi của cuộc gọi rõ ràng để Destructor

class some_class 
{ 
    // stuff 

public: 
    ~some_class() 
    { 
     delete dynamic_three; 
    } 

private: 
    classA one; 
    classB two; 
    classC* dynamic_three; 
} 

Khi thời gian tồn tại của một đối tượng kết thúc, sự tàn phá của nó là: (1) để gọi destructor của nó và (2) để tiêu diệt subobjects của nó trong cùng thứ tự mà chúng được khai báo trong định nghĩa lớp (= vị trí trong bộ nhớ).

Nhưng, nếu tôi có một cái gì đó như thế:

auto* ptr = new some_class(); 

// more stuff 

ptr->~some_class(); // l. X 

Bước (2) cũng được thực hiện? Tôi có nghĩa là, trong dòng X, là destructors của subobjects cũng được gọi là hoặc chỉ được thực hiện cơ thể của destructor some_class 's?

Trả lời

1

Khi tuổi thọ của đối tượng kết thúc, sự hủy diệt của nó là: (1) gọi hàm hủy của nó và (2) để tiêu diệt subobject của nó theo cùng thứ tự mà chúng được khai báo trong định nghĩa lớp (= vị trí trong ký ức).

và (3) bộ nhớ được cấp phát được giải phóng.

Bước (2) cũng được thực hiện?

Bước (2) có, nhưng không phải bước (3).

Nhưng nếu bạn có thể viết

auto* ptr = new some_class(); 

lưu ý rằng bạn cũng có thể viết

std::unique_ptr<ptr> ptr (new some_class()); 

mà sẽ gọi delete cho bạn (tất nhiên, chỉ sử dụng này nếu điều này phù hợp với nhu cầu của bạn, nhưng việc sử dụng điều này theo mặc định nếu bạn không chắc chắn).

+1

Um, no, destructor không có bộ nhớ được cấp phát miễn phí. Toán tử 'delete' thực hiện điều đó. –

2

Bước (2) cũng được thực hiện?

Có, nó được đảm bảo. Hành vi này là an toàn, nhưng lưu ý rằng trong trường hợp của bạn, bạn không có cách nào để lấy lại bộ nhớ của đối tượng một cách an toàn mà không phải xây dựng lại nó trước thông qua vị trí mới (trừ khi bạn đã vượt quá operator new cho đối tượng của mình và do đó bạn có thể đảm bảo bộ nhớ được phân bổ và sử dụng thỏa thuận khớp lệnh).

+0

Hmm. Tôi tự hỏi, nếu bạn sử dụng vị trí mới trên bộ nhớ đó, nó sẽ được an toàn để sau đó gọi 'xóa' trên đó? Hoặc đó sẽ là hành vi không xác định? –

+2

@BenjaminLindley Đó là an toàn ** miễn là hàm tạo không thể ném **. Nếu người xây dựng ném, bạn sẽ không may mắn. –

+0

Và chỉ để được tinh thể rõ ràng: "tái xây dựng nó" có nghĩa là tái xây dựng nó ** như cùng loại **. –

2

Hãy làm một bài kiểm tra:

class classA 
{ 
public: 
    ~classA() { cout << "~classA()" << endl; } 
}; 

class classB 
{ 
public: 
    ~classB() { cout << "~classB()" << endl; } 
}; 

class some_class 
{ 
public: 
    ~some_class() { cout << "~some_class()" << endl; } 

private: 
    classA one; 
    classB two; 
}; 

int main() 
{ 
    cout << "Start..." << endl; 

    auto* ptr = new some_class(); 

    ptr->~some_class(); 

    cout << "End." << endl; 
} 

Output:

Bắt đầu ...

~ some_class()

~ ClassB()

~ classA()

Kết thúc.

Vì vậy, tất cả các trình phá hủy được gọi và theo thứ tự ngược lại.

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