2013-03-04 2 views
0

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

class A 
{ 
public: 
    A(){}; 
    ~A(){} 
public: 
    int n; 
     virtual void Show(){ cout << "ShowA" << endl; }; 
}; 

class B : public A 
{ 
public: 
    B(){}; 
    ~B(){} 
    virtual void Show() { cout << "ShowB" << endl; } 
}; 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    B b; 
    A& a = b; //ShowB 
    A& a = (A)b; //ShowA 
    a.Show(); 

    //Extra: 
    A& extra = extra; 

    return 0; 
} 

Кроме того есть причина, почему A& extra = extra не запрещен, или просто потому, что мало значения запрещенных бессмысленных вещей?

+0

Итак ... в чем вопрос? – Yaniv

ответ

2
A& a = (A)b; 

Это создает временный объект типа A, копирование базового класса части b. Затем он пытается ссылаться на это временное.

К счастью, язык C++ не позволяет вам использовать (непостоянную) ссылку на временное, предотвращая случайную ошибку такого рода.

К несчастью, ваш компилятор предоставляет «языковое расширение», которое позволяет вам это делать, поэтому, если вы должны использовать этот компилятор, вам нужно быть более осторожным.

В общем, избегайте отливок C-типа, подобных чуме. Когда вам действительно нужно явное преобразование, используйте наиболее ограничительный C++-стиль, который вы можете, чтобы помочь ошибкам компилятора уловить.

Кроме того, есть причина, почему A& extra = extra не запрещено или просто потому, что для запрещенных бессмысленных вещей мало значения?

Нет веских оснований для этого; по-видимому, это не запрещено, потому что было бы довольно сложно запретить это, не запрещая законные заявления, такие как int i, &r=i; или void *p = &p;

+0

Отличный ответ, спасибо Майку! –

Смежные вопросы