2015-08-03 4 views
1

Я задал этот вопрос в интервью, и я не был уверен в поведении в следующем случае:понижающее приведение и виртуальные функции

class A 
{ 
     virtual fun1(){...} 
     virtual fun2(){...} 
}; 

class B : public A 
{ 
     virtual fun1(){...} 
     virtual fun2(){...} 
}; 

Теперь, если

A* AObj = new A; 
B* BObj = (B*) AObj; 

DoES BObj имеют доступ к Б методов из-за ключевого слова virtual или это не потому, что он указывает на объект AObj?

Может ли кто-нибудь помочь мне в том, как точно влияет на доступ вниз?

+0

Вы можете просто попробовать его на ideone.com или в любом месте: http://ideone.com/B7P6DN (это дает мне ошибку времени выполнения) – Melkon

ответ

4

Присвоение адреса объекта базового класса к производному классу указатель undefined behavior. Так что все может случиться: функции BObj могут вызывать функции B, могут вызывать функции A, могут вызывать сбои в программе или даже форматировать ваш жесткий диск. Все это будет зависеть от компилятора и его опций оптимизации.

1

В таких случаях (полиморфизм) тип указателя (BObj, здесь его тип не является B) является типом объекта, который он указывает на (A). , поэтому BObj является объектом базового класса и является неспособным выполнять дополнительную работу (функции), определенные в оцененном классе (B).

+0

, если этот ответ решил вашу проблему (очистил концепцию), отметьте это как ответ:) –

1

Прежде всего, это делает

A* AObj = new AObj(); 

B* BObj = AObj; 

не является безопасным на всех, потому что он присваивает адрес базового класса объекта (Parent) к указателю производного класса (ребенок). Таким образом, код будет ожидать, что объект базового класса будет иметь свойства производного класса.

Однако вы можете сделать это:

A* AObj = new AObj(); 

    B* BObj = dynamic_cast<B*>AObj; 

Это будет проверять, если Aobj могут быть назначены на BobJ или нет. Она возвращает адрес объекта, если он может, в противном случае он будет возвращать 0.

Таким образом, вы можете использовать его как:

B* BObj = dynamic_cast<B*>AObj; 
if(BObj) 
{ 
    //Now you can use it safely. 
} 
+0

Синтаксически вы сделали действительную точку, и я отредактирую свой вопрос соответствующим образом. Но это доступ к методу. Я немного туман. Спасибо! –

+0

@VishnuNair Как Петр правильно указал, что это неопределенное поведение, и я имел в виду то же самое, когда я сказал, что это небезопасно, использование BObj может или не может получить доступ к функции B или может привести к сбою кода. – Nishant

+0

@VishnuNair, если dynamic_cast находит, можно сбрасывать объект, он будет отображать и возвращать адрес, теперь, если есть дополнительные функции, определенные в производном классе, вы получите NULL. – Nishant