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); 
} 

chương trình rõ ràng là sai này (kể từ khi mẫu tham số là khác nhau) bị treo vớiLàm thế nào để gỡ lỗi một std :: ngoại lệ bad_cast

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

Có cách nào làm thế nào để có được chẩn đoán chính xác về những gì đã xảy ra, ngoài thông báo lỗi thời gian chạy? Cái gì đó, có thể chỉ ra lỗi int/float cho tôi? Tôi đang tìm kiếm một thông báo lỗi mô tả như

const GA1DArrayGenome<float> & không thể được đúc để const GA1DArrayGenome<int> &

Thậm chí tốt hơn, vì C++ loại có thể có được lông vào những thời điểm, công cụ này có thể nhận thấy sự khác biệt chính xác trong các mẫu tham số .

+2

Đây là một tác dụng phụ đáng tiếc của 'ngoại lệ std': bằng cách cố gắng để tránh phân bổ bộ nhớ thông điệp của họ là gần như vô ích, và rằng họ không có một dấu vết ngăn xếp nó là không thể biết được nơi họ đến từ một posteriori. Mặt khác, chúng có trọng lượng nhẹ ... –

Trả lời

7

Bạn cũng có thể từ bỏ sử dụng trực tiếp của dynamic_cast và bọc nó trong mẫu của riêng bạn máy móc:

#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

Bạn có thể tải chương trình của mình (được biên dịch với thông tin gỡ lỗi, ví dụ: -g trong gcc và glang) trong gbd, yêu cầu gdb bắt ngoại lệ với catch throw và sau đó xem ngăn xếp cuộc gọi để xem chính xác nơi ngoại lệ được ném.

std::bad_cast được ném khi dynamic_cast không hoạt động khi chạy.

+0

Nhưng điều đó không cho tôi biết điều gì đã xảy ra ... Mặt khác, tôi đoán rằng một loại sai được chỉ định là điều duy nhất có thể xảy ra ở đó, đúng không? – user7610

+1

@ user7610: vâng, thật không may, nó có thể đến từ bất cứ nơi nào sử dụng 'dynamic_cast' vì vậy trong một chương trình lớn, nó có thể khó phát hiện ... –

+0

Tiếp tục với ví dụ từ câu hỏi tôi có thể sử dụng' std :: cout < user7610

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