Cũng như trường hợp tiêu chuẩn gọi một hàm ảo từ các nhà xây dựng hoặc destructor của một đối tượng với chức năng ảo tinh khiết bạn cũng có thể có được một hàm ảo gọi tinh khiết (trên MSVC ít nhất) nếu bạn gọi một ảo chức năng sau khi đối tượng đã bị hủy. Rõ ràng đây là một điều khá xấu để thử và làm, nhưng nếu bạn đang làm việc với các lớp trừu tượng như các giao diện và bạn mess up thì đó là một cái gì đó mà bạn có thể nhìn thấy. Nó có thể có nhiều khả năng nếu bạn đang sử dụng giao diện tính tham chiếu và bạn có một lỗi đếm ref hoặc nếu bạn có một đối tượng sử dụng/đối tượng phá hủy cuộc đua điều kiện trong một chương trình đa luồng ... Điều về các loại purecall là nó thường ít dễ dàng để hiểu được những gì đang xảy ra như là một kiểm tra cho các 'nghi phạm thông thường' của các cuộc gọi ảo trong ctor và dtor sẽ đi lên sạch sẽ.
Để giúp gỡ lỗi các loại vấn đề này, bạn có thể, trong các phiên bản khác nhau của MSVC, thay thế trình xử lý trong suốt của thư viện thời gian chạy. Bạn thực hiện việc này bằng cách cung cấp chức năng của riêng bạn với chữ ký này:
int __cdecl _purecall(void)
và liên kết nó trước khi bạn liên kết thư viện thời gian chạy. Điều này cho phép bạn kiểm soát những gì xảy ra khi một purecall được phát hiện. Một khi bạn có quyền kiểm soát, bạn có thể làm điều gì đó hữu ích hơn trình xử lý tiêu chuẩn. Tôi có một người xử lý có thể cung cấp một dấu vết ngăn xếp của nơi mà các purecall đã xảy ra; xem tại đây: http://www.lenholgate.com/blog/2006/01/purecall.html để biết thêm chi tiết.
(Lưu ý bạn cũng có thể gọi _set_purecall_handler() để cài đặt trình xử lý của bạn trong một số phiên bản của MSVC).
Nguồn
2008-09-19 08:48:40
Bất kỳ lý do nào tại sao trình biên dịch không thể nắm bắt được điều này, nói chung? – Thomas
Tôi không thấy bất kỳ lý do kỹ thuật nào tại sao trình biên dịch không thể bắt được điều này. –
GCC chỉ cho tôi một cảnh báo: test.cpp: Trong hàm khởi tạo 'Cơ sở :: Cơ sở()': test.cpp: 4: cảnh báo: trừu tượng ảo 'virtual void Base :: doIt()' được gọi từ hàm tạo Nhưng nó không thành công tại thời gian liên kết. – Thomas