Я изучаю обработку исключений в C ++ и столкнулся с проблемой. Вот код:
#include<iostream>
#include<exception>
using namespace std;
class A
{
public:
virtual void f(void){}
};
class AA:public A
{
public:
void aa(void){};
};
int main(void)
{
A a;
try
{
dynamic_cast<AA>(a).aa();
}
catch(exception ex)
{
cout<<"["<<ex.what()<<"]"<<endl;
}
return 0;
}
Поэтому я подумал, что try catch позволит функции выполняться и покажет мне содержимое исключения, но мой компилятор не компилирует его. Я использую кодовый блок с GNU GCC. Пожалуйста, помогите мне и покажите, что мне нужно сделать, чтобы код работал так, как я планировал. большое спасибо.
dynamic_cast
может привести только к значению указателя или ссылке, что именно то, что говорит вам ошибка.
От $ 5.2.7 / 1 стандарта C ++.
Результат выражения dynamic_cast< T> (v) является результатом преобразования выражения v в тип T. T должен быть указателем или ссылкой на полный тип класса или «указателем на cv void».
Для того чтобы dynamic_cast
Чтобы сгенерировать исключение, когда объект не может быть преобразован, вам нужно привести его к ссылке. Измените это на следующее:
dynamic_cast<AA&>(a).aa();
// ^^^ cast to reference.
Как Johnsyweb указал dynamic_cast
всегда будет бросать std::bad_cast
когда преобразование не удается. Хотя std::bad_cast
происходит от std::exception
всегда полезно использовать исключение, которое наилучшим образом соответствует ожидаемому условию сбоя. Это предотвращает непреднамеренную интерпретацию других ошибок как неудачного приведения.
Чтобы применить это к вашему примеру, это может выглядеть как код ниже.
#include <iostream>
#include <typeinfo> // std::bad_cast
class A
{
public:
virtual void f(void){}
};
class AA:public A
{
public:
void aa(void){};
};
int main(void)
{
A a;
try
{
dynamic_cast<AA&>(a).aa();
}
catch(const std::bad_cast& ex)
{
std::cout << "["<<ex.what()<<"]" << std::endl;
}
return 0;
}
[Примечание, делать такие вещи, как using namespace std;
Настоятельно не рекомендуется, так как это может вызвать конфликты с идентификаторами в глобальном пространстве имен. Я удалил это в примере выше.]
Ваша проблема не с Обработка исключений, но с вашим динамический состав:
'AA' is not a reference or pointer
dynamic_cast
безопасно преобразует указатели а также Рекомендации в class
а не экземпляры.
Так что вы могли бы сделать:
dynamic_cast<AA&>(a).aa();
…который будет всегда потерпеть неудачу и бросить std::bad_cast
исключение.
Вы должны поймать наиболее специфический тип exception
что вы ожидаете и с рекомендуемый способ catch
по ссылке, Вы должны предпочесть:
catch (std::bad_cast const& ex)
Дальнейшее чтение: динамическое преобразование на cppreference.com.
Вы получаете ошибку компилятора, потому что ваш dynamic_cast
не указатель или ссылка.
Измените это на:
dynamic_cast<AA&>(a).aa();
… и вы получите правильное исключение.
Примечание: умные компиляторы, такие как g ++, также предупреждают:
предупреждение: dynamic_cast
на объекте (здесь a
никогда не преуспеет.
Так что лучше ограничить такой код для игры. В коде качества продукции dynamic_cast
должно выполняться только по указателю / ссылке.
Я просто имел дело с той же ошибкой, но в моем случае я переходил от указателя к указателю, поэтому остальные ответы здесь не применимы. Мое сообщение об ошибке немного отличалось: error: cannot dynamic_cast 'f()' (of type 'class B*') to type 'class A*' (target is not pointer or reference to complete type)
,
Основная причина в моем случае была гораздо более простой и обыденной.
Обратите внимание на добавление чтобы завершить тип в конце. Это заставило меня вспомнить, что я не включил заголовочный файл для своего класса, который я использовал. Это был не неизвестный символ, потому что A*
был вперед объявлен с class A;
в заголовочном файле, в результате чего он существует, но не является полным, отсюда и ошибка.
Решение в моем случае состояло в том, чтобы включить заголовочный файл для класса, к которому я приводил.
Это не проблема вопроса, которая была задана выше, но, как видно из моего случая, может привести к тому же типу ошибки.