Бьерн Страуструп.
Язык программирования С++
351
вращать круг (Circle) нет смысла, но для объекта, представляющего производный класс, это может
потребоваться). Опыт показывает, что программистам, воспитанным на таких языках как С или Паскаль,
трудно избежать этой ловушки. Стиль программирования этих языков требует меньше
предусмотрительности, а при создании библиотеки такой стиль можно просто считать небрежностью.
Может возникнуть вопрос, почему в интерфейс с системой динамической информации о типе включена
условная операция приведения ptr_cast(), а не операция is_base(), которая непосредственно
определяется с помощью операции has_base() из класса Type_info. Рассмотрим такой пример:
void f(dialog_box& db)
{
if (is_base(&db,dbox_w_str)) {
//
является ли db базовым
//
для dbox_w-str?
dbox_w_str* dbws = (dbox_w_str*) &db;
//
...
}
//
...
}
Решение с помощью ptr_cast ($$13.5) более короткое, к тому же здесь явная и безусловная операция
приведения отделена от проверки в операторе if, значит появляется возможность ошибки,
неэффективности и даже неверного результата. Неверный результат может возникнуть в тех редких
случаях, когда система динамической идентификации типа распознает, что один тип является
производным от другого, но транслятору этот факт неизвестен, например:
class D;
class B;
void g(B* pb)
{
if (is_base(pb,D)) {
D* pb = (D*)pb;
//
...
}
//
...
}
Если транслятору пока неизвестно следующее описание класса D:
class D : public A, public B {
//
...
};
то возникает ошибка, т.к. правильное приведение указателя pb к D* требует изменения значения
указателя. Решение с операцией ptr_cast() не сталкивается с этой трудностью, поскольку эта операция
применима только при условии, что в области видимости находятся описания обеих ее параметров.
Приведенный пример показывает, что операция приведения для неописанных классов по сути своей
ненадежна, но запрещение ее существенно ухудшает совместимость с языком С.
Достарыңызбен бөлісу: