Началось с того, что мне предложили взглянуть некий на “интересный” код. Там было что-то вроде:
... 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
? Зря!