Программирование >>  Полиморфизм без виртуальных функций в с++ 

1 ... 48 49 50 [ 51 ] 52 53 54 ... 144


void reverse(int* elements, int length of element array); ...

void reverse{int* v, int n) {

. . .

Как всегда, одни находят такой стиль отвратительным, другие (в том числе я) - вполне разумным. Как бы то ни было, програ.мм в указанно.м стиле написано очень .много. Но, введя именованные аргу.меиты, мы не сможем изменить ни одно имя в стандартно распрострапяемо.м заголовочно.м файле без риска сделать неработоспособным пользовательский код. Поставщика.м заголовочных файлов для одних и тех же библиотек, папри.мер Posix или X Windows, придется договариваться об и.менах аргументов.

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

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

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

Я опасался, что и.менованные аргументы могут замедлить постепенный переход от традиционных приемов программирования к абстракции данных и далее к объектно-ориентированному стилю. В профам.мах, которые, на мой взгляд, лучше всего написаны и удобны для сопровождения, длинные списки аргументов -редкость. Многие пользователи отмечали, что переход к объектно-ориентированному стилю сопровождается укорачиванием списков аргументов: то, что раньше передавалось в виде аргументов или глобальных переменных, теперь становится локальным состоянием объекта. Основываясь на опыте, я ожидаю, что среднее число аргу.ментов будет меньше двух, а функций, и.меющих более двух аргументов, почти не останется. Отсюда следует, что именованные аргументы окажутся наиболее полезными как раз в таких программах, которые мы считаем написанными плохо. Так следует ли вводить новое средство, поощряющее и.менпо тот стиль программирования, который мы хотели бы изжить? Такая постановка вопроса, проблема сов.мести.мости и некоторые мелкие детали стали причиной единодушного отказа принять предложение об именованных аргументах.

6.5.1.1. Альтернативы именованным аргументам

Но если мы отказываемся от именованных аргу.ментов, то как сократить длину списка аргу.ментов в примере с классо.м window? Кажущаяся сложность уже



class bordered window : public window { public:

bordered window(border b=single, color bc=blue) : window(standard,0,0,100,100,black,b,be) { }

Этот прием ограничивает использование функции несколькими наиболее употребительными формами и потому код и поведение программы становятся более однообразньши. Другой способ - ввести явные операции для задания установок, отличных от подразумеваемых:

class w args { wintype wt;

int ulcx, ulcy, xz, yz; color wc, be; border b; WSTATE ws; public:

w args() установки no умолчанию

: wt(standard), ulcx(O), ulcy(O), xz(lOO), yz(lOO), wc(black), b(single), bc(blue), ws(open) { }

отменить умолчания:

w args& ysize(int s) { yz=s; return *this; } w args& Color(color c) { wc=c; return *this; } w args& Border(border bb) { b = bb; return *this; } w args& Border color(color c) { bc=c; return *this; } . ..

class window { . . .

window(w args wa); CKonnposaTb настройки wa . . .

Это дает нам нотационное удобство, в некоторой степени эквивалентное тому, которое обеспечивают именованные аргументы:

window w; окно по умолчанию

window w( w argsО.Color(green).ysize(150) );

уменьшена за счет аргументов по умолчанию. Еше один распространенный прием - дополнительные типы для представления наиболее типичных вариантов:

class colored window : public window { public:

colored window{color c=black)

: window{standard,0,0,100,100,c) { }



Существенное преимущество такого способа состоит в том, что он облегчает передачу объектов, представляющих аргументы, между различными частями программы.

Естественно, все эти приемы можно использовать в любом сочетании. В совокупности они позволяют сократить список аргументов и, следовательно, свести иа нет потреб1Юсть в именованных.

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

6.5.2. Ограниченные указатели

Компилятору Fortran разрешено предполагать, что два массива, переданных функции в качестве аргументов, пе перекрываются. Функция С++ не вправе делать таких допущений. В результате подпрогра.мма, написанная на Fortran, оказывается на 15-30% быстрее в зависимости от качества компилятора и машинной архитектуры. Особенно заметную экономию дают векторные операции на машинах, имеющих специальную векторную аппаратуру (например, Cray).

Учитывая повышенное внимание к эффективности С, все вышесказанное рассматривалось, как досадная оплошность. В комитет ANSI С поступило предложение решить эту проблему с помощью механизма, названного пса lias. При наличии этого ключевого слова считалось бы, что у указателя нет псевдонимов (то есть никакие два указателя не указывают на одну и ту же область памяти). К сожалению, предложение поступило слишком поздно и в очень непроработанном виде. Это обстоятельство побудило Денниса Ричи написать открытое письмо, начинающееся слова.ми: никаких noalias, это даже не подлежит обсуждению .

Понятно, что после этого сообщество пользователей С и С++ без особой охоты возвращалось к проблеме псевдонимов. Но вопрос был очень важен для пользователей С на платформе Cray, поэтому Майк Холли (Mike Holly) из компании Cray, в конце концов, представил улучшенное предложение по этой проблеме группе по численным расширения.м С (NCEG) и комитету по С++. Идея заключалась в том, чтобы дать программисту возможность декларировать отсутствие у указателя псевдонимов, объявив его с ключевым словом restrict:

void* memcopy{void*restrict sl, const void* s2, size t n);

Поскольку уже сказано, что у sl нет псевдонимов, нет необходимости указывать restrict еще и для s2. Ключевое слово restrict применяется к оператору * точно так же, как модификаторы const и volatile. Это предложение должно устранить преимущество Fortran в эффективности, приняв в С правила, действующие в Fortran (правда, лишь выборочно).

Комитет по С++, внимательно относившийся к любому предложению, способному повысить эффективность языка, потратил немного времени на обсуждение данного предложения, но все же оно было отклонено, насколько я помню, единогласно. Вот основные мотивы:

□ расширение небезопасно. Если объявить указатель как restrict, то компилятору позволено предполагать, что у него пет псевдонимов. Од!1ако



1 ... 48 49 50 [ 51 ] 52 53 54 ... 144

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика