2015-12-14 9 views
11

. Какого рода отливка происходит здесь (в B::get())?Класс, основанный на литье, основывается на базе

class A { 
public: 
    A() : a(0) {} 
    int a; 
}; 

class B : public A { 
public: 
    A* get() { 
     return this; //is this C-style cast? 
    } 
}; 

int main() 
{ 
    B b; 
    cout << b.get()->a << "\n"; 

    system("pause"); 
    return 0; 
} 

Я видел этот вид кода в известном API. Лучше ли делать static_cast<A*>(this);?

+8

Нет никакого каста на всех, только неявное преобразование. Листинг - это явное преобразование. – molbdnilo

ответ

9

Это стандартное преобразование указателя на основе базовой базы. Правила заключаются в том, что указатель на D с некоторыми const/volatile квалификациями может быть преобразован в указатель на B с теми же квалификаторами, если B является базовым классом D.

Стандартные преобразования - это неявные преобразования со встроенными значениями и являются отдельными понятиями для таких вещей, как static_cast или приведениями в стиле C.

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

+0

Строго говоря, «можно преобразовать в указатель на« B »с теми же * или более * квалификаторами» –

+2

Я предлагаю конкретно ответить на его вопрос: «Нет, лучше использовать« static_cast »- на самом деле, это худшая практика. Всегда избегайте приведения, если они вам не нужны ». –

+0

@MartinBonner Не согласен! Неявные броски являются источником всякого рода сумасшедших ошибок. Иногда я хочу, чтобы C++ даже не имел их вообще ... Ничего плохого в том, чтобы быть явным. – Barry

3

Это неявное преобразование к предку. Неявные преобразования, как правило, безопасны, и они не могут делать вещи static_cast не могут. Они на самом деле еще более ограничены: вы можете сделать необработанный downcast с static_cast, но не с неявным преобразованием.

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