2013-07-10 15 views
7

Aşağıdaki kodla ilgili bir sorunum var. Gördüğümüz gibi, A'nın yapıcısı tarafından C'nin yapıcısına atılan istisnayı halihazırda ele aldım, neden tekrar ana fonksiyonda bir istisna ile uğraşmak zorundayım?C++ kurucu başlatıcı listesi istisnalar atar

#include <iostream> 

class WException : public std::exception 
{ 
public: 
    WException(const char* info) : std::exception(info){} 
}; 

class A 
{ 
public: 
    A(int a) : a(a) 
    { 
     std::cout << "A's constructor run." << std::endl; 
     throw WException("A constructor throw exception."); 
    } 

private: 
    int a; 
}; 

class B 
{ 
public: 
    B(int b) : b(b) 
    { 
     std::cout << "B's constructor body run." << std::endl; 
     throw WException("B constructor throw exception"); 
    } 

private: 
    int b; 
}; 

class C : public A, public B 
{ 
public: 
    C(int a, int b) try : A(a), B(b) 
    { 
     std::cout << "C's constructor run." << std::endl; 
    } 
    catch(const WException& e) 
    { 
     std::cerr << "In C's constructor" << e.what() << std::endl; 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    try 
    { 
     C c(10, 100); 
    } 
    catch(const WException& e) 
    { 
     std::cerr << "In the main: " << e.what() << std::endl; 
    } 

    return 0; 
} 
+2

istisna aslında 'C' yapıcısının dışarı yaymak mu gördünüz mü? Eğer değilse, neden tekrar yakalayın? – arne

+1

Ayrıca, 'main() 'da istisnayı yakalamanızı kim önerdi? Ona bu soruyu sorun! – Nawaz

+1

@Nawaz, Veya onu, geez. Bu meslekte kadın olmadığı hiç merak değil: p – chris

cevap

16

yapamazsınız aslında yakalamak yapıcı bir istisna. Sen halledebilirsin, ama onu ya da başka bir istisnayı yeniden başlatmalısın. sebebi nesne bütünlüğü ve nesne ömürleri hakkındadır: a inşaatı atar

ise c bir parçası başlatıldı ve tamamen eksik olduğunu edilmemiştir - a yaşam boyu asla başlar. a bir işaretçi veya bir std::optional olmak zorunda aksi halde, C isteğe bağlı bir parçası değildir (C++ 14 yana - daha önce boost::optional).

Peki onun hayati parçalarından biri inşa edilemez bir C eğer monte edersiniz? Yapamazsın. c hiçbir zaman tam bir nesne olarak mevcut olmayacaktır, bu yüzden yapıcıdan normal şekilde çıkmanın hiçbir yolu yoktur. Bu nedenle, bir üye nesnenin yapımı başarısız olursa, tüm nesnenin inşası başarısız olur, yani , bir istisna atmak zorundadır. Eğer C::C 'ın catch bloğunda bir istisna yoksa

, derleyici sizin için yapacaktır.

, C++ standart, §15.3,15: Kontrol bir kurucu ya da yıkıcı işlevi-deneyin-bloğunun bir işleyici ucu ulaşırsa

anda ele durum rethrown edilir.

bu konu üzerinde daha geniş bir tedavi için

, http://www.gotw.ca/gotw/066.htm

+0

Hepinize teşekkürler, özellikle @Arne Mertz. Ve C++ Standardı herşeyi açıklıyor, :-) – JavaBeta