...
class A { virtual void f() {} };
class B {};
int main() {
A a;
try {
B& b = dynamic_cast<B&>(a);
if (&b == 0) {
// ...
}
} catch (...) {
std::cout << "Got it!" << std::endl;
}
return 0;
}
Я слегка выпал в осадок от уведенного, а в частности, от строки "if (&b == 0) {". До сего времени я пребывал в осознании факта, что ссылка в С++ либо существует и указывает на реальный объект, либо ее нет вообще. И если тут приведение типа к "B&" не срабатывает, то будет исключение, и управление все равно улетит в другое место, и проверять как-либо "b" бессмысленно.
Но тут мне объяснили, что в данном конкретном случае код может компилироваться, когда у компилятора выключена поддержка исключений. И эта проверка как раз защита от этого.
Ну да ладно. Оставим это на откуп странным компиляторам на AIX и SUN, и людям, использующим исключения, но почему-то компилирующие с принудительным их выключением в компиляторе.
Меня заинтересовал другой вопрос: как вообще ссылка может существовать отдельно от объекта. Оказывается, может:
int& a = *(int*)0;
int main() { a = 123; }
Данный код прекрасно компилируется Студией (2010) и компилятором SUN (этот хоть предупреждение выдает), и также прекрасно падается при запуске по понятой причине.
Вы получили ссылку в качестве параметра и думаете, что она лучше чем указатель, так как ее не надо проверять на null? Зря!