P>почему при вызове виртуального метода базового класса после dynamic_cast вызывается exception?
потому что так задуман dynamic_cast
в случае, если ты осуществляешь невалидное преобразование (а именно это ты и делаешь), dynamic_cast вернет тебе 0, а ты это должен проверить. Он затем и придуман, чтобы проверять и сообщать, если что не так.
А если ты будешь кастить не указатели, а ссылки, но dynamic_cast сам кинется в тебя исключением std::bad_cast.
doIt — невиртуальная, так ее вызывать нельзя с нулевым указателем (неопределенное поведение), но ты, нарушая правила вызвал и тебе "повезло", кстати, попробуй в ней что-нибудь кому-нибудь присвоить.
Следующая функция — виртуальная, чтоб ее вызвать нужна втбл, указатель на которую д.б. в объекте и тут тебе уже не "повезло" — у тебя нулевой указатель.
Of course, the code must be complete enough to compile and link.
class A
{
public:
virtual ~A(){}
void fun()
{
i_ = 0;
}
private:
int i_;
};
class B:public A
{
};
int main()
{
A a;
B * pb = dynamic_cast<B *>(&a);
pb->fun();
return 0;
}
Of course, the code must be complete enough to compile and link.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>doIt — невиртуальная, так ее вызывать нельзя с нулевым указателем (неопределенное поведение), но ты, нарушая правила вызвал и тебе "повезло", кстати, попробуй в ней что-нибудь кому-нибудь присвоить.
вот-те раз... действительно нулл... this = 0x00000000 как же так?.. а почему неопределенное поведение? и как это она зовет метод от нулевого указателя? объясните пожалуйста
P>вот-те раз... действительно нулл... this = 0x00000000 как же так?..
Объект типа А объектом типа В не является, поэтому при попытке такого преобразования dynamic_cast вернет 0 для случая указателя, либо бросит std::bad_cast для случая ссылок(как уже сказад jazzer)
P>а почему неопределенное поведение? и как это она зовет метод от нулевого указателя? объясните пожалуйста
Потому что такой вызов аналогичен (*p).doIt() — разыменование нулевого указателя. "Работает" т.к. doIt — обычная функция, которой в качестве невидимого тебе параметра передается 0 (this).
//pseudo-code, not C++
//p->doIt();
doIt(p);
Of course, the code must be complete enough to compile and link.
Здравствуйте, pasenger, Вы писали:
P>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>doIt — невиртуальная, так ее вызывать нельзя с нулевым указателем (неопределенное поведение), но ты, нарушая правила вызвал и тебе "повезло", кстати, попробуй в ней что-нибудь кому-нибудь присвоить.
P>вот-те раз... действительно нулл... this = 0x00000000 :wow: как же так?..
см. мой предыдущий ответ P>а почему неопределенное поведение?
по определению. Разыменование нулевого указателя — оно самое и есть. P>и как это она зовет метод от нулевого указателя?
как умеет, так и зовет
обычно форматирует винчестер, но сегодня тебе повезло P>объясните пожалуйста
воспользуйся поиском, тыщу раз уже все это обсуждалось