Đó là "có thể" theo một nghĩa nào đó (nếu mục tiêu của bạn là lớp dẫn xuất vẫn trừu tượng nếu không). Nhưng nó sẽ không cho kết quả bạn muốn: Bởi vì trình biên dịch sẽ tạo ra một destructor chính nó ngầm nếu người lập trình đã không làm như vậy.
Đó là để không có thể buộc tác giả của lớp dẫn xuất tuyên bố rõ ràng một hàm tạo.
(chỉnh sửa: Giống như @chubsdad
ghi chú
lưu ý, lỗi trong mã cụ thể của bạn là do bạn cần xác định trình phá hủy được khai báo rõ ràng của lớp cơ sở).
Sửa: Chỉ cần cho vui, có là tình huống mà necessiate một constructor tuyên bố một cách rõ ràng. Hãy xem xét những điều sau
struct Viral {
struct Dose { };
protected:
~Viral() throw (Dose) { }
};
struct Base {
virtual ~Base() throw() { }
};
struct Derived : Base, Viral { };
Mã này sẽ không biên dịch vì mặc nhiên tuyên bố ~Derived
sẽ có một đặc điểm kỹ thuật ngoại lệ throw (Dose)
đó là lỏng hơn so với những gì ~Base
có - vì vậy nó vi phạm các yêu cầu mà overriders sẽ không có một đặc điểm kỹ thuật ngoại lệ lỏng hơn. Bạn sẽ cần phải tuyên bố một cách rõ ràng destructor một cách thích hợp
struct Derived : Base, Viral { ~Derived() throw() { } };
Nhưng điều này không thực sự là một giải pháp cho vấn đề của bạn, bởi vì các lớp thừa kế cần phải "hợp tác" vào một trong hai bắt nguồn từ Viral
hoặc đặt nó như là một thành viên dữ liệu không tĩnh . Nó cũng rất xấu xí :)
Edit: Sau đây có vẻ là một cách tiêu chuẩn phù hợp để làm điều đó
struct Viral {
struct Dose { };
protected:
~Viral() throw (Dose) { }
};
struct Base : virtual Viral {
virtual ~Base() throw() { }
};
Clang và GCC (starting with v4.6) từ chối bất kỳ lớp được thừa kế của Base
có một hàm hủy ngầm được khai báo ngầm, bởi vì nó có một đặc tả ngoại lệ không tương thích (bất kỳ lớp dẫn xuất nào sẽ gọi trực tiếp ~Viral
, thay vì gián tiếp bằng cách gọi ~Base
, tiêu chuẩn nói). Comeau chấp nhận điều này, nhưng tôi mạnh mẽ nghi ngờ rằng nó không phù hợp về vấn đề này.
Nguồn
2010-09-13 12:51:04
+1 cho ví dụ có thể là ví dụ hiệu quả nhất về không gian mà tôi đã thấy từ trước tới nay. :-D – DevSolar
Tại sao? Điểm bắt buộc người dùng viết thêm mã là gì? Nếu bạn đã làm sạch, hãy tự làm, đừng đặt gánh nặng lên người dùng của bạn; nếu bạn không, nó vô dụng. Bạn có thể cung cấp một ví dụ về tình huống thực sự hữu ích không? –
@Matthieu M .: Mã được tạo ra chỉ vượt qua void * và con được tạo ra sau đó cha mẹ sau đó các chức năng ngẫu nhiên theo thứ tự ngẫu nhiên để vượt qua params/con cho cha mẹ. Rất bừa bộn. Mỗi cấu trúc sẽ nhận được một void * và tôi cần phải nhớ để làm sạch nó lên. Có lẽ auto_ptr sẽ giải quyết nó nhưng tôi không chắc chắn về tác dụng phụ và một nửa của các lớp học dường như được thực hiện. –