Có nên dùng try catch trong c không
Xử lý ngoại lệ - exception handling hiệu quả với try, catch, throw thông qua ví dụ trong C++.
Mọi đoạn chương trình được viết ra đều tiềm ẩn khả năng sinh lỗi. Có thể là lỗi chủ quan do lập trình sai hoặc có thể là lỗi khách quan do dữ liệu hay trạng thái của hệ thống (thiếu memory, mạng bị corrupt …). Không dễ dàng để kiểm soát tất cả trường hợp của chương trình, đặc biệt các lỗi liên quan đến số học, bộ nhớ, … Vì thế, việc giải quyết các ngoại lệ để ứng dụng chúng ta tránh được những rủi ro là 1 điều không kém phần quan trọng. Tổng quanException – Ngoại lệ là cơ chế thông báo và xử lý những vấn đề tiềm ẩn phát sinh (giống như lỗi runtime) trong chương trình bằng cách chuyển quyền điều khiển đến những hàm đặc biệt nhằm tách phần xử lý lỗi ra khỏi thuật toán chính. Một ngoại lệ là một đối tượng chứa thông tin về lỗi và truyền thông tin của lỗi cho bộ phận xử lý để có những hướng giải quyết phù hợp. Ngoại lệ có thể thuộc bất kì kiểu dữ liệu bất kỳ của C++:
Cơ chế của ngoại lệCơ chếQuy trình gọi hàm và trả về trong trường hợp bình thường: Quy trình ném và bắt ngoại lệ tại Cơ chế xử lý ngoại lệ của C++ có 3 tính năng chính:
Hướng giải quyếtMuốn bắt exception tại vị trí nào của chương trình thì ta phải đặt tại đó 1 đoạn code nhằm kiểm tra ngoại lệ. Đoạn chương trình này được đóng gói trong 1 khối try-block. Khi một ngữ cảnh thực thi tiếp nhận và truy nhập một ngoại lệ được coi là bắt ngoại lệ (catch the exception) thì nó được truyền đến phần xử lý ngoại lệ (exception handler). Song, nếu không xảy ra bất cứ ngoại lệ nào thì chương trình được build bình thường và các bộ xử lý đều được bỏ qua. Và quá trình truyền ngoại lệ từ ngữ cảnh thực thi hiện hành đến mức thực thi cao hơn - được gọi là ném 1 ngoại lệ (throw an exception) – bằng cách sử dụng từ khóa Ví dụ đoạn chương trình sau: // Exceptions #include Đoạn code dưới xử lý ngoại lệ bên trong khối lệnh
Biểu thức ném ngoại lệ chấp nhận 1 tham số(trong trường hợp này là 1 chuỗi kí tự “String!”) được thông qua để xử lý ngoại lệ. Đoạn xử lý ngoại lệ được khai báo vời từ khóa catch ngay sau kết thúc khối try. Cú pháp bắt ngoại lệ cũng tương tự như khai báo 1 hàm thông thường với 1 tham số. Loại tham số truyền vào catch rất quan trọng vì các loại của đối số này thông qua biểu thức ném để kiểm tra và chỉ khi phù hợp thì các ngoại lệ được bắt mới được xử lý. Khi ngoại lệ được ném đi, hệ thống xử lý ngoại lệ sẽ kiểm tra các kiểu được liệt kê trong khối catch theo thứ tự liệt kê:
Do khó có thế kiểm soát mọi trường hợp xảy ra trong chương trình và để mức thực thi hiện hành không bị kết thúc giữa chừng ta có thể sử dụng dấu “…” làm đối số truyền vào catch, phần xử lý này sẽ bắt bất kỳ ngoại lệ nào được ném (bao gồm cả những ngoại lệ không thể giải quyết). View Full Version : Khi nào nên dùng try...catch trong lập trình C# zkday2686 22-12-2008, 06:43 PM Chào các bạn. nay rảnh rổi ngồi nghĩ bậy bạ nghĩ ra 1 câu hỏi, nó cũng điên điên nhưng đưa lên đây anh em cùng thảo luận. (\'o) Trong bộ .NET nó cung cấp cho chúng ta một cái tool dùng để chặn các 'Ngoại lệ' lúc runtime rất hay đó là try...catch. Nhưng zkday được biết dùng nó thì làm chương trình chậm đi Vậy vấn đề đặt ra ở đây là khi nào chúng ta cần dùng nó. khi nào không (:P) trung 22-12-2008, 07:33 PM hê hê mình thấy là dùng trong kết nối database là nhiều nhất bởi khi kết nối database có rất nhiều lỗi phát sinh (mình kiến thức còn nông cạn có gì sai chỉ giáo thêm :D) vf6.0 22-12-2008, 11:06 PM mình nghĩ khi nào mình cảm thấy đoạn code có khả năng phát sinh lỗi thì mình sẽ dùng nó để bắt lỗi hoặc khi kết nối với database thì mình nên dùng nó để có thể xử lý lỗi của database theo ý mình chứ đừng để chương trình tự xử lý. darkan 22-12-2008, 11:44 PM @ vf6.0 : trigger is evil ^^! Khi bạn dùng trigger, bạn đã đẩy quá trình kiểm soát lỗi xuống server. Vừa tăng tải server, vừa góp phần gây nghẽn đường truyền ^^! Những lỗi do người dùng nhập hoàn toàn có thế kiểm soát trên client ^^! Hơn nữa,try ... catch để bắt exception. Exception có thể do người dùng tự sinh ra (throw exception) hoặc do lỗi run time. Nếu bạn dùng trigger bạn sẽ xử lý thế nào nếu đường truyền hỏng hoặc db chưa được start? Vì dùng try... catch sẽ có thời gian xử lý lâu hơn là trigger Và nữa là nếu bạn không có try.. catch thì khi có exception nó sẽ out ngay lập tức chứ không có chiện tự xử lý đâu ^^! M$ chưa có làm cái compiler thông minh đến như thế được đâu ^^! @ trung : try... catch được ứng dụng rất nhiều, không phải chỉ với db bạn nhé. Nếu bạn đọc qua java sẽ thấy try...catch được dùng trong hầu hết các hàm của java. @ zk : Tự đọc nhé ^^! http://msdn.microsoft.com/en-us/library/aa664733(VS.71).aspx Làm nhiều việc hơn thì phải chậm hơn chứ sao ^^! And do it for safe ^^! Cheers! P/S: Có một số trường hợp không cần dùng, ví dụ như các hàm private thì thường có try ... catch cũng được,không có cũng chẳng sao ^^! zkday2686 23-12-2008, 12:32 AM @trung: ngoài cái vấn đề này, còn gì nữa không nhỉ ? @vf6.0: ngoài những điều anh Dark nói thì mình xin bổ sung một số ý kiến sau. @dark: Thank anh;). Mà hình như anh hiểu nhầm ý của em thì phải :). darkan 23-12-2008, 07:26 AM @ zk : 2 cái link anh đưa trên là nguyên lý của try... catch. Khi code có thể xảy ra một số lỗi nằm ngoài ý muốn, nên nếu muốn hạn chế chương trình crash thì tất cả đều nên dùng try catch ^^! Tuy nhiên các hàm private thì đều phải gọi qua các hàm public, cho nên nếu các hàm public đã dùng try catch thì exception của hàm private đều được catch ở hàm public. Nên có dùng try catch ở các hàm private hay ko ko ảnh hưởng lắm đến chương trình, dùng hay ko đều được cả ^^! Túm lại là cái nào là public thì nên dùng try catch ^^! Cheers! trung 23-12-2008, 09:14 AM trong C# bật try... catch hay ko cũng dc , chứ trong Java mà ko bật try... catch thì khi compile là bị lỗi ( thật khó hiểu ) trung 23-12-2008, 09:30 AM tiện thể cho mình hỏi : thread (nghĩa tiếng anh là sợi chỉ) mình gặp hoài nhưng ko hiểu thuật ngữa nó gọi là gì , và ứng dụng làm gì ,giải thích thêm giùm mình :o meoconlongvang 23-12-2008, 11:17 AM tiện thể cho mình hỏi : thread (nghĩa tiếng anh là sợi chỉ) mình gặp hoài nhưng ko hiểu thuật ngữa nó gọi là gì , và ứng dụng làm gì ,giải thích thêm giùm mình :o Thread có thể tạm hiểu là một luồng. Về bản chất nó là một hàm nhưng có khả năng chạy song song với các hàm khác. Khi bạn gọi hàm thì bạn phải chờ nó chạy xong thì bạn mới có thể chạy tiếp. Còn nếu tạo thread thì hàm đó sẽ chạy song song và bạn ko cần phải chờ nó trả về mà vẫn chạy tiếp được. PS : lần sau bạn ko được hỏi làm loãng chủ đề như vậy nữa nha. zkday2686 23-12-2008, 12:28 PM Hix thank anh :) hôm qua em đã đọc 2 cái link anh đưa nó giải thích cho em được câu nói này của anh ;) ví dụ như các hàm private thì thường có try ... catch cũng được,không có cũng chẳng sao ^^! tức giờ ta bỏ được 1 trường hợp phải dùng try...catch là các hàm private rồi. :D Vì: Trước sau gì hàm private cũng được 1 hàm nào đó gọi lại. Nếu hàm private gặp Exception thì nó sẽ 'quăng' ra catch của hàm public gọi nó. :) --> tiết kiệm được 1 vài chổ try....catch. :D NamVoDang 23-12-2008, 08:01 PM Hầu như mấy cái library đều có exception của riêng nó, mình dùng thì mình phải catch chứ chẳng nhẽ để nó crash ra đấy à???. Ví dụ std có quả std::exception khỏi nói rồi, Ogre cũng có Ogre::Exception, CEGUI cũng có CEGUI::exception, OIS cũng có OIS::exception, mình dùng thì mình phải catch chứ. Vì: Trước sau gì hàm private cũng được 1 hàm nào đó gọi lại. Nếu hàm private gặp Exception thì nó sẽ 'quăng' ra catch của hàm public gọi nó. --> tiết kiệm được 1 vài chổ try....catch. VD: int main() Gì chứ nói lý thuyết, học thuật thì tui "rất bị" dỡ. Thấy cái article này trên CodeProject, rất hay, anh em đọc và "bình lựng": http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx kidkid 25-12-2008, 10:19 AM Cứ chỗ nào dễ phát sinh lỗi thì dùng try catch, tuy nhiên theo em nghĩ nếu có thể tự bắt được thì nên làm không lạm dụng try catch nó sẽ làm chậm chương trình vd: Chỗ này có thể bắt lỗi b = 0 được, nên bắt không dung try catch. NamVoDang 25-12-2008, 06:25 PM Gì chứ nói lý thuyết, học thuật thì tui "rất bị" dỡ Cứ chỗ nào dễ phát sinh lỗi thì dùng try catch, tuy nhiên theo em nghĩ nếu có thể tự bắt được thì nên làm không lạm dụng try catch nó sẽ làm chậm chương trình vd:
Chỗ này có thể bắt lỗi b = 0 được, nên bắt không dung try catch. Đây là file Main.cpp của dự án VHFOS mình đang tham gia. #include int main(int argc,char* argv[]) Lotus::Engine::getInstance().loop(); Lotus::Engine::Destroy(); return 0; Và khi chạy game thì chả thấy bị sụt đi FPS nào ngay cả khi load cả một cái terrain to đùng vào. Với chương trình nhỏ, tỉ mỉ có thể thấy được sự chênh lệch, nhưng khi nó ăn nhiều CPU và ngốn một đống RAM thì sự chênh lệch đó chả có nghĩa lý gì so với việc đang chơi thì tưng một phát, chương trình bị crash còn gamer thì chả hiểu mô tê gì và lập trình viên cũng chả hiểu gì luôn ngoài việc thỉnh thoảng tôi đang chơi thì bị lỗi, bị lỗi và bị lỗi, chưa kể còn gây ức chế cho user vì chương trình kết thúc một cách đầy bạo lực mà chả có lời giải thích cũng như xin lỗi hay chỉ dẫn nào từ phía lập trình viên. Spam: Chiều nay vừa thi xong hai môn Hóa, Sử hô hô. kidkid 25-12-2008, 06:37 PM Với các hàm catch trên theo kid NVD chỉ cần dùng assert để tiện cho debug. Còn lại ném chung vào 1 catch thông báo cho gamer. Trở lại vấn đề chính, ý zkday nói là khi nào dùng, và khi nào không nên dùng, do đó ý của tớ là chỉ dùng khi những đoạn code đó có khả năng phát sinh lỗi cao, như kết nối database, internet, những gì chúng ta không control được mà thôi. NamVoDang 25-12-2008, 07:27 PM Còn lại ném chung vào 1 catch thông báo cho gamer. Trở lại vấn đề chính, ý zkday nói là khi nào dùng, và khi nào không nên dùng, do đó ý của tớ là chỉ dùng khi những đoạn code đó có khả năng phát sinh lỗi cao, như kết nối database, internet, những gì chúng ta không control được mà thôi. zkday2686 25-12-2008, 11:19 PM @Nam, kid: Cảm ơn cả 2 bạn ;) @TQN: thank anh :). @all: hi! chúng ta cùng 'mỗ sẻ' cái link anh TQN đưa nhé :) darkan 29-12-2008, 11:32 AM Cái link của bác TQN rất hay nhớ ^^! Mỗi tội nó tập trung vào handle exception nhiều hơn là dùng try catch thế nào ^^! Trong cái link của bác TQN có 2 điểm đáng lưu ý về sử dụng try catch. Put a single catch (Exception ex) per thread When in doubt, don't Assert, throw an Exception Don't forget that Debug.Assert is removed from release code. When checking and doing validation, it's often better to throw an Exception than to put an assertion in your code. Save assertions for unit tests, for internal loop invariants, and for checks that should never fail due to runtime conditions (a very rare situation, if you think about it). Cái này có lẽ giải quyết được vấn đề đang tranh cãi của NVD ví lại kid ^^! @NVD : Không phải cái nào cũng control được đâu (:P). Một số thứ phát sinh kiểu đang connect zô 1 cái server nào đấy thì đạp văng cái dây mạng đi chẳng hạn ^^! Lỗi kiểu ấy thì chỉ có cách dùng exception thôi, control thế nào được ^^! @kid : Mỗi exception có nội dung riêng, message riêng. Gộp chung lại rất khó debug. Lấy luôn cái vd của NVD cho nhanh(mặc dù cách xử lý exception như thế lại dở ^^!). Nếu catch 1 cái general exception thì khi đem cho khách hàng sử dụng, nếu có 1 cái phát sinh thì móm ^^! Có biết được lỗi ở đâu, do thằng nào gây ra đâu ^^! OWickedFox 31-12-2008, 02:07 PM Tránh dùng Try Catch khi viết virus :D (trích từ một câu học được "Bạn sẽ không muốn thấy con virus của bạn ngốn 2,3 chục Mb RAM, because that's stupid"). Nhưng nếu bít lợi dụng Try Catch để gài bẫy những Anti Virus Engine thì rất được hoan nghênh. Ví dụ bắt lỗi chia cho 0. :D vBulletin® Version 4.2.2, Copyright © 2022 vBulletin Solutions, Inc. All rights reserved. Administer by Kevin Hoang |