Kısa cevap: Algılanabilir Hata Yönetimi 1 , Algılanabilir Hata Kullanımı 2 ve Mantıklı Hata Kullanımı 3'ü Niklas Frykholm tarafından okuyun. Aslında, sen blogdayken o blogdaki tüm makaleleri oku. Her şeye katılıyorum demeyeceğim ama çoğu altın.
İstisnaları kullanmayın. Bir sürü sebep var. En büyükleri listeleyeceğim.
Gerçekten daha yavaş olabilirler, ancak bu daha yeni derleyicilerde biraz azaltılabilir. Bazı derleyiciler, istisnaları tetiklemeyen kod yolları için "sıfır yükü istisnalarını" destekler (bu biraz yalan olsa da, istisna işleme için çalıştırılabilir / dll boyutunuzu şişirmek için hala fazladan veri kullanımı gerekir). Sonuç olarak, evet, istisnaları kullanmak daha yavaş ve performans açısından kritik kod yollarında kesinlikle bunlardan kaçınmalısınız. Derleyicinize bağlı olarak, etkin olmalarını sağlamak ek yük ekleyebilir. Her zaman kod boyutunu şişirir, daha ziyade, çoğu durumda, günümüzün donanımında performansı ciddi şekilde etkileyebilen önemli ölçüde şişirir.
İstisnalar, kodu çok daha kırılgan hale getirir . Bir grafik üzerinde (şu anda ne yazık ki bulamıyorum) temelde bir grafikte istisna güvenli kodla istisna güvenli olmayan kod yazmanın zorluğunu gösteren bir grafik var ve eski önemli ölçüde daha büyük bir çubuktur. Sadece istisnalar dışında çok sayıda ufak tefek şey var ve istisnaları güvenli görünen ama gerçekten değil gibi kod yazmanın birçok yolu var . Tüm C ++ 11 komitesi bile buna şaşırdı ve std :: unique_ptr komutunu doğru kullanmak için önemli bir yardımcı işlev eklemeyi unuttu ve bu yardımcı işlevlerde bile, bunları kullanmak için kullanmayacağından ve çoğu programcının kazandığından daha fazla yazı yazdı. Yapmazlarsa neyin yanlış olduğunu bile anlama.
Daha belirgin olarak, oyun endüstrisi için, bazı konsolların satıcı tarafından tedarik edilen derleyiciler / çalışma zamanları tamamen istisnaları tam olarak desteklemiyor, hatta hiç desteklemiyor. Kodunuz istisnalar kullanıyorsa, yine de bugün ve yaşta, yeni platformlara taşımak için kodunuzun bölümlerini yeniden yazmak zorunda kalabilirsiniz. (Söz konusu konsolların piyasaya sürülmesinden sonraki 7 yıl içerisinde bunun değişip değişmediğinden emin değilsiniz; istisnalar kullanmıyoruz, derleyici ayarlarında bile devre dışı bıraktıklarından, bu yüzden konuştuğum birinin yakın zamanda kontrol ettiğini bile bilmiyorum.)
Genel düşünme çizgisi oldukça açık: istisnai durumlar için istisnalar kullanın . Programınıza girdiğinde bunları kullanın. "Ne yapacağımı bilemiyorum, belki de başkası yapar, bu yüzden bir istisna atacağım ve ne olacağını göreceğim." Başka hiçbir seçenek mantıklı olmadığında bunları kullanın. Yanlışlıkla küçük bir hafıza sızdırması veya bir kaynağı temizleyememeniz veya uygun akıllı tutamaçların kullanımını karıştırdığınızdan emin olmamanız durumunda bunları kullanın. Diğer tüm durumlarda, onları kullanmayın.
Örnekteki gibi bir kodla ilgili olarak, sorunu çözmenin birkaç başka yolu vardır. En sağlamlarından biri - basit örneğinizde mutlaka en ideal olmasa da - monadik hata türlerine yaslanmaktır. Yani, createText () bir tamsayı yerine özel bir tanıtıcı türü döndürür. Bu tutamaç türü, metni güncellemek veya kontrol etmek için erişim sağlayıcılara sahiptir. Tutamaç bir hata durumuna getirildiyse (createText () başarısız oldu), daha sonra tutamağa yapılan çağrılar sessizce başarısız olur. Ayrıca, hatalı olup olmadığını ve varsa son hatanın ne olduğunu görmek için tanıtıcıyı sorgulayabilirsiniz. Bu yaklaşım diğer seçeneklerden daha fazla ek yüke sahiptir, ancak oldukça sağlamdır. Tek bir işlemin üretimde başarısız olabileceği, ancak yapamadığınız / kazanamadığınız / kazanamadığınız bazı bağlamlarda uzun bir işlem dizisi uygulamanız gerektiğinde kullanın.
Monadik hata işlemenin uygulanmasına bir alternatif, özel tanıtıcı nesneler kullanmak yerine, bağlamsal nesnedeki yöntemleri geçersiz tanıtıcı kimlikleriyle incelikle ele almasıdır. Örneğin, createText () başarısız olduğunda -1 döndürürse, o zaman bu tutamaçlardan birini alan m_statistics işlevine yapılan çağrılar, -1 iletilirse dikkatlice çıkmalıdır.
Aynı şekilde, hata basma işlemini gerçekten başarısız olan işlevin içine de koyabilirsiniz. Örneğinizde, createText () muhtemelen neyin yanlış gittiği hakkında daha fazla bilgiye sahip olduğundan, günlüğe daha anlamlı bir hata verebilir. Bu durumda, hatayı işleme / yazdırma işleminin arayanlara iletilmesinin çok az yararı vardır. Arayanların kullanımı özelleştirmesi (veya bağımlılık enjeksiyonunu kullanması) gerektiğinde bunu yapın. Bir hata günlüğe kaydedildiğinde ortaya çıkabilecek bir oyun içi konsola sahip olmanın iyi bir fikir olduğunu ve burada da yardımcı olacağını unutmayın.
Herhangi bir aklı başında bir ortamda başarısız olmasını beklemeyeceğiniz aramalar için en iyi seçenek (yukarıdaki bağlantılı makalelerde sunulan) - bir istatistik sistemi için metin blobları oluşturma eylemi gibi - sadece fonksiyona sahip olmaktır. bu başarısız oldu (örneğinizdeki createText) iptal edildi. Bir şey tamamen kazanılmadığı sürece createText () 'in üretimde başarısız olmayacağından emin olabilirsiniz (örneğin, kullanıcı yazı tipi veri dosyalarını silmiş veya bir nedenden dolayı sadece 256 MB belleğe sahip vs.). Bu vakaların çoğunda, başarısızlık gerçekleştiğinde yapılacak iyi bir şey bile yoktur. Bellek yetersiz? Kullanıcıya OOM hatasını göstermek için hoş bir GUI paneli oluşturmak için gerekli bir tahsis bile yapamayabilirsiniz. Eksik fontlar? Kullanıcıya hataları göstermeyi zorlaştırır. Neyin yanlışsa,
Siz sadece (a) hatayı bir günlük dosyasına kaydettiğiniz ve (b) sadece normal kullanıcı eylemlerinden kaynaklanmayan hatalar üzerine yaptığınız sürece, kilitlenme tamamen iyidir.
Aynı şeyi pek çok sunucu uygulaması için söyleyemem, kullanılabilirliğin kritik olduğu ve bekçi izleme sisteminin yeterli olmadığı, ancak oyun istemcisi geliştirmeden oldukça farklı olduğu söylenebilir. Ayrıca, diğer dillerin istisna işleme olanakları, yönetilen ortamlar olduğundan ve C ++ 'nın istisna güvenliği sorunlarına sahip olmadığından C ++ C gibi ısırma eğilimi göstermediğinden, sizi C / C ++ kullanmaya zorla yönlendiririm. Sunucular, oyun müşterileri gibi asgari gecikme garantilerinden çok paralellik ve verim üzerinde yoğunlaşmaya meyilli olduğu için performans kaygıları da hafifletilir. Atıcılar ve benzerleri için aksiyon oyunu sunucuları bile, C # ile yazıldığında oldukça iyi işleyebilir, çünkü, örneğin, FPS istemcilerin yapma eğiliminde olduğu gibi donanımı nadiren zorluyorlar.