ошибка: невозможно dynamic_cast … (цель не указатель или ссылка)

Я изучаю обработку исключений в 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. Пожалуйста, помогите мне и покажите, что мне нужно сделать, чтобы код работал так, как я планировал. большое спасибо.

9

Решение

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; Настоятельно не рекомендуется, так как это может вызвать конфликты с идентификаторами в глобальном пространстве имен. Я удалил это в примере выше.]
19

Другие решения

Ваша проблема не с Обработка исключений, но с вашим динамический состав:

'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.

5

Вы получаете ошибку компилятора, потому что ваш dynamic_cast не указатель или ссылка.
Измените это на:

dynamic_cast<AA&>(a).aa();

… и вы получите правильное исключение.

Примечание: умные компиляторы, такие как g ++, также предупреждают:
предупреждение: dynamic_cast на объекте (здесь aникогда не преуспеет.

Так что лучше ограничить такой код для игры. В коде качества продукции dynamic_cast должно выполняться только по указателю / ссылке.

4

Я просто имел дело с той же ошибкой, но в моем случае я переходил от указателя к указателю, поэтому остальные ответы здесь не применимы. Мое сообщение об ошибке немного отличалось: 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; в заголовочном файле, в результате чего он существует, но не является полным, отсюда и ошибка.

Решение в моем случае состояло в том, чтобы включить заголовочный файл для класса, к которому я приводил.

Это не проблема вопроса, которая была задана выше, но, как видно из моего случая, может привести к тому же типу ошибки.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector