Язык программирования C++ для профессионалов



     тур выходного дня украина |       

Игнорирование статического контроля типов - часть 2


class X { // pseudo code, not C++ f() g() }

class Y { g() h() }

class Z { h() f() }

используемые некоторыми функциями бестипового проекта:

k(a, b, c) // pseudo code, not C++ { a.f() b.g() c.h() }

Здесь обращения

X x Y y Z z

k(x,y,z) // ok k(z,x,y) // ok

будут успешными, поскольку k() просто требует, чтобы ее первый параметр имел операцию f(), второй параметр - операцию g(), а третий параметр - операцию h(). С другой стороны обращения

k(y,x,z); // fail k(x,z,y); // fail

завершатся неудачно. Этот пример допускает совершенно разумные реализации на языках с полным динамическим контролем (например, Smalltalk или CLOS), но в С++ он не имеет прямого представления, поскольку язык требует, чтобы общность типов была реализована как отношение к базовому классу. Обычно примеры, подобные этому, можно представить на С++, если записывать утверждения об общности с помощью явных определений классов, но это потребует большого хитроумия и вспомогательных средств. Можно сделать, например, так:

class F { virtual void f(); };

class G { virtual void g(); };

class H { virtual void h(); };

class X : public virtual F, public virtual G { void f(); void g(); };

class Y : public virtual G, public virtual H { void g(); void h(); };

class Z : public virtual H, public virtual F { void h(); void f(); };

k(const F& a, const G& b, const H& c) { a.f(); b.g(); c.h(); }

main() { X x; Y y; Z z;

k(x,y,z); // ok k(z,x,y); // ok

k(y,x,z); // error F required for first argument k(x,z,y); // error G required for second argument }

Обратите внимание, что сделав предположения k() о своих аргументах явными, мы переместили контроль ошибок с этапа выполнения на этап трансляции. Сложные примеры, подобные приведенному, возникают, когда пытаются реализовать на С++ проекты, сделанные на основе опыта работы с другими системами типов. Обычно это возможно, но в результате получается неестественная и неэффективная программа. Такое несовпадение между приемами проектирования и языком программирования можно сравнить с несовпадением при пословном переводе с одного естественного языка на другой. Ведь английский с немецкой грамматикой выглядит столь же неуклюже, как и немецкий с английской грамматикой, но оба языка могут быть доступны пониманию того, кто бегло говорит на одном из них.

Этот пример подтверждает тот вывод, что классы в программе являются конкретным воплощением понятий, используемых при проектировании, поэтому нечеткие отношения между классами приводят к нечеткости основных понятий проектирования.




Содержание  Назад  Вперед