Có, các biến tự động sẽ bị hủy ở cuối khối mã kèm theo. Nhưng hãy tiếp tục đọc.
Tiêu đề câu hỏi của bạn hỏi liệu trình hủy sẽ được gọi khi biến không nằm trong phạm vi. Có lẽ những gì bạn muốn hỏi là:
Foo của hàm hủy có được gọi vào cuối main() không?
Với mã mà bạn cung cấp, câu trả lời cho câu hỏi đó là không kể từ khi đối tượng Foo có thời gian lưu trữ năng động, như chúng ta sẽ thấy ngay.
Lưu ý ở đây những gì biến tự động là:
Foo* leedle = new Foo();
Ở đây, leedle
là biến tự động sẽ bị hủy diệt. leedle
chỉ là một con trỏ. Điều mà leedle
chỉ định là không phải có thời lượng lưu trữ tự động và sẽ không bị hủy. Vì vậy, nếu bạn làm điều này:
void DoIt()
{
Foo* leedle = new leedle;
}
Bạn bị rò rỉ bộ nhớ được phân bổ bởi new leedle
.
Bạn phảidelete
bất cứ điều gì mà đã được phân bổ với new
:
void DoIt()
{
Foo* leedle = new leedle;
delete leedle;
}
này được thực hiện đơn giản hơn nhiều và mạnh mẽ hơn bằng cách sử dụng con trỏ thông minh. Trong C++ 03:
void DoIt()
{
std::auto_ptr <Foo> leedle (new Foo);
}
Hoặc trong C++ 11:
void DoIt()
{
std::unique_ptr <Foo> leedle = std::make_unique <Foo>();
}
con trỏ thông minh được sử dụng như là các biến tự động, như trên, và khi họ đi ra khỏi phạm vi và bị phá hủy, họ tự động (trong destructor) delete
đối tượng đang được trỏ đến. Vì vậy, trong cả hai trường hợp trên, không có rò rỉ bộ nhớ.
Hãy cố gắng xóa một chút ngôn ngữ tại đây. Trong C++, các biến có thời lượng lưu trữ. Trong C++ 03, có 3 khoảng thời gian lưu trữ:
1: tự động: Biến có thời lượng lưu trữ tự động sẽ bị hủy ở cuối khối mã kèm theo.
xem xét:
void Foo()
{
bool b = true;
{
int n = 42;
} // LINE 1
double d = 3.14;
} // LINE 2
Trong ví dụ này, tất cả các biến có thời gian lưu trữ tự động. Cả hai b
và d
sẽ bị phá hủy tại dòng 2. n
sẽ bị phá hủy tại dòng 1.
2: tĩnh: Một biến với thời gian lưu trữ tĩnh sẽ được phân bổ trước khi chương trình bắt đầu, và bị phá hủy khi chương trình kết thúc.
3: động: Một biến với thời gian lưu trữ năng động sẽ được phân bổ khi bạn phân bổ nó sử dụng các hàm cấp phát bộ nhớ động (ví dụ, new
) và sẽ bị phá hủy khi bạn tiêu diệt nó sử dụng các hàm cấp phát bộ nhớ động (ví dụ, delete
).
Trong ví dụ ban đầu của tôi trên:
void DoIt()
{
Foo* leedle = new leedle;
}
leedle
là một biến với thời gian lưu trữ tự động và sẽ bị tiêu diệt tại nẹp kết thúc. Điều mà leedle
trỏ tới có thời lượng lưu trữ động và không bị hủy trong mã ở trên. Bạn phải gọi delete
để deallocate nó.
C++ 11 cũng cho biết thêm một khoảng thời gian lưu trữ thứ tư:
4: chủ đề: Biến với thời gian lưu trữ chủ đề được phân bổ khi thread bắt đầu và deallocated khi thread kết thúc.
Không, bạn cần phải tự gọi chính mình là 'xóa leedle'. – juanchopanza
Bạn có thể trả lời và giải thích tại sao không? – Tux
Có câu hỏi trong tiêu đề, Không cho câu hỏi trong nội dung. Bạn phải tự xóa mọi thứ bạn mới. Nếu bạn sử dụng 'new' trong hàm khởi tạo (miễn là không có ngoại lệ nào được ném ra), bạn có thể gọi' delete' trong destructor và nó sẽ dọn sạch bộ nhớ cho bạn. – Rapptz