2014-04-30 12 views
5
class GAGenome { 
    virtual void method(){}; 
}; 

template <class T> 
class GAArray { 
}; 

template <class T> 
class GA1DArrayGenome : public GAArray<T>, public GAGenome { 
}; 

int main() { 
    GA1DArrayGenome<float> genome; 
    const GAGenome & reference = genome; 
    auto cast = dynamic_cast<const GA1DArrayGenome<int> &>(reference); 
} 

To oczywiście źle programu (ponieważ parametr szablonu jest inny) wywala zJak debugować wyjątek std :: bad_cast

terminate called after throwing an instance of 'std::bad_cast' 
    what(): std::bad_cast 
Aborted (core dumped) 

Czy istnieje sposób, jak uzyskać precyzyjne diagnostykę, co poszło nie tak, poza komunikat o błędzie w czasie wykonywania? Coś, co może mi wskazywać na błąd int/float? Szukam opisowy komunikat o błędzie podobny

const GA1DArrayGenome<float> & nie mogą być oddane do const GA1DArrayGenome<int> &

nawet lepiej, ponieważ C++ typy mogą dostać owłosione czasami narzędzie mógłby zauważyć dokładną różnicę w parametrze szablonu .

+2

To niefortunny efekt uboczny z 'std' wyjątkami: próbując uniknąć alokacji pamięci ich wiadomości jest niemal bezużyteczne, a ponieważ nie mają śladu stosu, prawie niemożliwe jest wiedzieć, skąd pochodzą a posteriori. Z drugiej strony są lekkie ... –

Odpowiedz

7

Można również zrezygnować z bezpośrednich zastosowań dynamic_cast i zawinąć go w swoim własnym maszyn Szablon:

#include <sstream> 

class my_bad_cast: public std::bad_cast { 
public: 
    my_bad_cast(char const* s, char const* d): _source(s), _destination(d) { 
#ifdef WITH_BETTER_WHAT 
     try { 
      std::ostringstream oss; 
      oss << "Could not cast '" << _source 
       << "' into '" << _destination << "'"; 
      _what = oss.str(); 
     } catch (...) { 
      _what.clear(); 
     } 
#endif 
    } 

    char const* source() const { return _source; } 
    char const* destination() const { return _destination; } 

#ifdef WITH_BETTER_WHAT 
    virtual char const* what() const noexcept { 
     return not _what.empty() ? _what.c_str() : std::bad_cast::what(); 
    } 
#endif 

private: 
    char const* _source; 
    char const* _destination; 
#ifdef WITH_BETTER_WHAT 
    std::string _what; 
#endif 
    // you can even add a stack trace 
}; 

template <typename D, typename S> 
D my_dynamic_cast(S&& s) { 
    try { 
     return dynamic_cast<D>(std::forward<S>(s)); 
    } catch(std::bad_cast const&) { 
     throw my_bad_cast(typeid(S).name(), typeid(D).name()); 
    } 
} 
2

można załadować swój program (skompilowany z informacjami debug, np -g w gcc i glang) w GBD, powiedz gdb złapać wyjątki catch throw a następnie spojrzeć na stosie wywołań, aby zobaczyć dokładnie, gdzie wyjątek.

std::bad_cast jest generowany, gdy dynamic_cast kończy się niepowodzeniem w czasie wykonywania.

+0

Ale to nie mówi mi, co poszło nie tak ... Z drugiej strony, myślę, że wskazany niewłaściwy typ jest jedyną rzeczą, która może pójść nie tak, prawda? – user7610

+1

@ user7610: tak, jest, niestety, może pochodzić z dowolnego miejsca, które używa 'dynamic_cast', więc w dużym programie może być trudno wykryć ... –

+0

Kontynuując przykład z pytania, mogę użyć' std :: cout < user7610