Liệu trình phá hủy của lớp cơ sở có được gọi nếu một đối tượng ném một ngoại lệ trong hàm tạo không?Liệu trình phá hủy của lớp cơ sở có được gọi là một đối tượng ném một ngoại lệ trong hàm tạo không?
Liệu trình phá hủy của lớp cơ sở có được gọi là một đối tượng ném một ngoại lệ trong hàm tạo không?
Trả lời
Nếu ngoại lệ được ném trong khi xây dựng, tất cả các đối tượng phụ được tạo trước đó sẽ bị hủy đúng cách. Các chương trình sau đây chứng minh rằng cơ sở chắc chắn bị phá hủy:
struct Base
{
~Base()
{
std::cout << "destroying base\n";
}
};
struct Derived : Base
{
Derived()
{
std::cout << "throwing in derived constructor\n";
throw "ooops...";
}
};
int main()
{
try
{
Derived x;
}
catch (...)
{
throw;
}
}
đầu ra:
throwing in derived constructor
destroying base
(Lưu ý rằng destructor của một con trỏ bản địa không có gì, đó là lý do tại sao chúng ta thích RAII qua con trỏ nguyên.)
Có. Quy tắc là mọi đối tượng có hàm tạo đã hoàn tất thành công sẽ bị hủy theo ngoại lệ. Ví dụ:
class A {
public:
~A() {}
};
class B : public A {
public:
B() { throw 0; }
~B() {}
};
~ A() được gọi. ~ B() không được gọi;
EDIT: hơn nữa, giả sử bạn có các thành viên:
struct A {
A(bool t) { if(t) throw 0; }
~A() {}
};
struct B {
A x, y, z;
B() : x(false), y(true), z(false) {}
};
gì xảy ra là: x được xây dựng, y ném, x là destructed (nhưng không phải y cũng không z).
Khi một ngoại lệ được ném ra, các destructors đang kêu gọi tất cả (phụ) đối tượng có nhà xây dựng đã được chạy thành công. Điều này mở rộng cho các thành viên dữ liệu và các lớp cơ sở như nhau.
Ví dụ, đối với mã này
struct base {};
struct good {};
struct bad {
bad() {throw "frxgl!";}
};
struct test : public base {
std::string s;
good g;
bad b;
test() {}
};
trước test
's constructor được thực thi, đầu tiên các nhà xây dựng cho lớp cơ sở được gọi, sau đó các nhà thầu cho s
, g
, và b
. Chỉ khi kết thúc thành công, hàm tạo cho test
được thực hiện. Khi ngoại lệ được ném trong khi xây dựng b
, các trình tạo lớp cơ sở cũng như các hàm tạo cho các thành viên dữ liệu s
và g
đã được thực hiện đầy đủ, do đó các trình phá hủy của chúng được chạy. Hàm khởi tạo của test
chính nó và của b
chưa được chạy thành công, do đó các trình phá hủy của chúng không chạy.
Từ tài liệu chuẩn, 15,3-11,
Các lớp cơ sở xây dựng hoàn chỉnh và các thành viên của một đối tượng sẽ bị hủy diệt trước khi vào xử lý của một hàm try- khối của một nhà xây dựng hoặc destructor cho đối tượng đó.
Trích dẫn hay, nhưng nó không trả lời câu hỏi. – fredoverflow
@FredOverflow, Vâng cảm ơn ... Cập nhật ngay bây giờ .. :) – liaK
- 1. Trình xây dựng và trình phá hủy của lớp cơ sở có được gọi với các hàm khởi tạo không?
- 2. Trình hủy có được gọi khi một nhà xây dựng ủy nhiệm ném không?
- 3. Trình phá hủy trình biên dịch tạo ra của lớp cơ sở trừu tượng có phải là ảo không?
- 4. Destructor không được gọi khi một ngoại lệ được ném
- 5. Ném ngoại lệ từ một hàm tạo trong .NET
- 6. Tại sao hàm tạo lớp cơ sở trừu tượng của tôi không được gọi khi một đối tượng được khởi tạo bởi trình gỡ rối WCF?
- 7. Thiết bị hủy không được gọi sau khi phá hủy đối tượng được sắp xếp mới
- 8. Tôi có cần gọi rõ ràng trình phá hủy ảo cơ sở không?
- 9. ném ngoại lệ từ hàm tạo trong C++
- 10. Không có ngoại lệ loại DataAccessException có thể được ném; loại ngoại lệ phải là một lớp con của Throwable
- 11. Có thể hoàn thành được gọi sau khi một nhà xây dựng ném một ngoại lệ?
- 12. Nếu một ngoại lệ được ném luôn luôn là một bản sao của đối tượng ngoại lệ, tại sao không phải là hàm tạo bản sao này được gọi?
- 13. Lớp nào có getClass() báo cáo bên trong một hàm tạo của một lớp cơ sở
- 14. C++ - Nếu một đối tượng được khai báo trong một vòng lặp, thì hàm hủy của nó có được gọi là ở cuối vòng lặp không?
- 15. Hủy tác vụ đang ném một ngoại lệ
- 16. Trình tạo bản sao cơ sở không được gọi là
- 17. weak_ptr của một lớp cơ sở, trong khi shared_ptr là của một lớp dẫn xuất?
- 18. Ném một ngoại lệ từ std :: call_once
- 19. Tại sao không phải là destructors được gọi là khi một ngoại lệ uncaught là ném trong C + + trong quá trình tạo mảng?
- 20. Tại sao destructor lớp cơ sở được gọi là đối tượng dẫn xuất khi destructor của lớp dẫn xuất là không ảo?
- 21. Trình tạo đối tượng Excel VBA và hàm hủy
- 22. Có thể tạo một lớp dẫn xuất từ một hàm tạo lớp cơ sở không?
- 23. Gọi hàm tạo lớp cơ sở sau (không có trong danh sách khởi tạo) trong C++
- 24. Bắt ngoại lệ trong hàm tạo
- 25. Gọi hàm bị ghi đè từ một lớp cơ sở?
- 26. Làm thế nào để bạn phá hủy một đối tượng trong Perl một cách rõ ràng?
- 27. Tại sao đối tượng TStrings của tôi bị hủy trước khi trình phá hủy của tôi có cơ hội chạy?
- 28. Tiêu hủy temporaries chuỗi trong trường hợp ngoại lệ ném
- 29. Gọi hàm ảo của lớp dẫn xuất từ hàm tạo lớp cơ sở?
- 30. Những gì destructors được chạy khi constructor ném một ngoại lệ?
Tôi không thể nhớ - nếu bạn không bắt được ngoại lệ, thì trình phá hủy lớp cơ sở được đảm bảo được gọi hoặc được tính là một phần của "thư giãn" và do đó nó được xác định hoặc không phải là một ngoại lệ không bị bắt? –
@Steve: Nếu không có sự bắt, căn cứ không bị phá hủy khi tôi thực hiện, vì vậy tôi * đoán * nó không được bảo đảm, nhưng ai biết ...:-) – fredoverflow
Đó là lý do tại sao nó là một ý tưởng tốt để đặt một nắm bắt và tái ném vào chính để buộc các stack được unwound một cách chính xác. –