2010-06-28 32 views
17

Wikipedia nói rằng "Một đoạn mã được cho là ngoại lệ an toàn, nếu lỗi thời gian chạy trong mã sẽ không tạo ra hiệu ứng xấu, chẳng hạn như rò rỉ bộ nhớ, dữ liệu được lưu trữ bị cắt xén hoặc đầu ra không hợp lệ. Mã an toàn ngoại lệ phải thỏa mãn các bất biến được đặt trên mã ngay cả khi ngoại lệ xảy ra. "An toàn ngoại lệ trong Qt

Và có vẻ như chúng tôi cần xử lý ngoại lệ cho sự an toàn ngoại lệ. Mặt khác, xử lý ngoại lệ không phải là rất phổ biến trong các ứng dụng Qt miễn là tôi thấy.

Thực tiễn tốt nhất của bạn trong Qt là gì để thỏa mãn sự an toàn ngoại lệ? Bạn sử dụng gì thay vì xử lý ngoại lệ?

+1

QT là một thư viện rất cũ và rất nghèo khi nói đến an toàn ngoại lệ. Hãy xem xét cách tất cả các widget phải được phân bổ đống nhưng không có con trỏ thông minh nào cho RAII. Điều tốt nhất bạn có thể làm là phân bổ chúng thành một auto_ptr và giải phóng bộ nhớ cho bố cục/bố cục khi chèn.Họ có một số quy định cơ bản như QMutexLocker kể từ khi ném trong khi một mutex bị khóa sẽ là thảm họa, nhưng có rất nhiều thứ họ cần cung cấp hoặc toàn bộ công việc bạn sẽ phải tự mình sử dụng qt theo cách an toàn ngoại lệ . – stinky472

+8

@ stinky472: Sai. [QSharedPointer] (http://doc.trolltech.com/4.6/qsharedpointer.html) – MSalters

+0

@ stinky472: Bộ công cụ GUI nào cho phép tiện ích được phân bổ theo chồng? Và tại sao bạn muốn làm điều này? Âm thanh như một đối số "người rơm". – kevinarpe

Trả lời

10

C++ có một cơ chế rất mạnh mẽ cho excpetion-an toàn. Destructors được chạy cho tất cả các biến nằm ngoài phạm vi do một ngoại lệ. Điều này khác với các ngôn ngữ như Java, nơi an toàn ngoại lệ yêu cầu người lập trình để có được các điều khoản catchfinally.

Hành vi C++ gọi destructors hoạt động liền mạch với các đối tượng Qt trên ngăn xếp. Tất cả các lớp Qt đều có các bộ hủy và không yêu cầu dọn dẹp thủ công. Hơn nữa, QSharedPointer<T> có thể được sử dụng để quản lý các đối tượng Qt được phân bổ heap; khi con trỏ cuối cùng đi ra khỏi phạm vi đối tượng bị phá hủy. Điều này bao gồm trường hợp con trỏ ra khỏi phạm vi do một ngoại lệ.

Vì vậy, ngoại lệ an toàn chắc chắn có mặt trong Qt. Nó chỉ trong suốt.

+2

Tôi nghĩ rằng vấn đề với QSharedPointer là nó không được sử dụng ở nhiều nơi. Ví dụ, một QLayout mong đợi QWidget * với kỳ vọng rằng QLayout trở thành người quản lý bộ nhớ cho nó. Chúng tôi không thể sử dụng QSharedPointer ở đây vì QLayout được cho là sẽ xóa tiện ích khi nó bị xóa khỏi bố cục. :-( – stinky472

+3

Bài viết gốc của tác giả đã nói, "xử lý ngoại lệ không phải là rất phổ biến trong các ứng dụng Qt miễn là tôi thấy" điều đó là chính xác. Sự tồn tại của QSharedPointer thay đổi không có gì bởi vì một vài phần của QT API và các ví dụ của nó thực sự sử dụng nó Thay vào đó chúng ta có các ví dụ như nút QButton * = new QButton (...); QVBoxLayout * layout = new QVBoxLayout (...); Thư viện, phần lớn, không được mã hóa là ngoại lệ an toàn. cần được giải quyết và làm cho nhiều bộ phận của thư viện chấp nhận và lưu trữ QSharedPointer sẽ là một giải pháp rất tốt. – stinky472

2

Thực hành tốt nhất của tôi là không sử dụng (hoặc ít nhất tránh chúng càng nhiều càng tốt) ngoại lệ C++ trong mã dựa trên Qt, điều này khiến chúng không phải là vấn đề. Qt không thực sự là lý do cho điều này mặc dù, tôi chỉ đơn giản là cảm thấy ngoại lệ thường làm cho mọi thứ phức tạp hơn một cách không cần thiết hơn là họ nên làm. Nhưng nó giúp Qt chính nó là chủ yếu là ngoại lệ rắc rối miễn phí ... :)

7

Qt là (chủ yếu) không an toàn ngoại lệ: http://doc.qt.io/archives/4.6/exceptionsafety.html

Mặt khác đối phó với trường hợp ngoại lệ chính xác trong lập trình sự kiện điều khiển được rất khó , tốt nhất là là để tránh chúng khi sử dụng mã lỗi Qt và vượt qua.

+10

Tại sao xử lý ngoại lệ một cách chính xác trong lập trình hướng sự kiện là rất khó? – metdos

1

Lớp Qt là exception neutral như đã nêu trong documentation.

Bạn nên gắn các giá trị boolean để xử lý các điều kiện lỗi, giống như chính Qt.

Không sử dụng ngoại lệ bên trong đã được thực hiện vì lý do di chuyển, vì Qt phải hỗ trợ nhiều nền tảng khác nhau (tính di động và ngoại lệ không kết hợp tốt).

Một lần nữa, từ các tài liệu:

Hiện nay, các trường hợp sử dụng chỉ được hỗ trợ cho việc khôi phục từ ngoại lệ ném trong Qt (ví dụ do ra khỏi bộ nhớ) là để thoát khỏi vòng lặp sự kiện và làm một số ngẫu nhiên trước thoát khỏi ứng dụng. trường hợp sử dụng điển hình:

QApplication app(argc, argv); 
... 
try { 
    app.exec(); 
} catch (const std::bad_alloc &) { 
    // clean up here, e.g. save the session 
    // and close all config files. 

    return 0; // exit the application 
} 
+4

Lưu ý rằng Qt có lịch sử quay trở lại thời điểm ngoại lệ mới. Tính di động trong thế kỷ 21 dễ dàng hơn rất nhiều. – MSalters

+0

Bạn nói đúng, tôi nên nhấn mạnh điều đó. Mặc dù tôi không thực sự biết nhiều về ngoại lệ và Symbian, đặc biệt là với các phiên bản mới hơn. Tôi biết các phiên bản cũ hơn đã sử dụng cơ chế xử lý ngoại lệ khác nhau đáng kể. –

+0

Symbian là một nỗi đau; không có bất ngờ cho những năm 80 của EPOC. Nhưng Qt và Symbian không liên quan đến _that_. Symbian có nguồn gốc từ Psion; Qt tại TrollTech. – MSalters

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