|
Программирование >> Оптимизация возвращаемого значения
Такой подход соответствует традиционной семантике С и С++, а поведение программ, использующих данный прием, не изменится с переходом на компиляторы, обеспечивающие поддержку bool. Недостаток же этого подхода состоит в том, что при перегрузке функций тип bool нельзя отличить от int. Оба варианта неплохи. Выбирайте тот из них, который лучше всего подходит в каждом конкретном случае. Вторая новая конструкция на самом деле состоит из четырех, это операторы приведения типа: static cast, const cast, dynainic cast и reinterpret cast. Если вы не знакомы с перечисленными конструкциями, обратитесь к правилу 2, где содержится полная информация о них. Они не только делают больше, чем операторы приведения типов в стиле С, но и лучше выполняют все поставленные программистом задачи. Поэтому для приведения типов в данной книге я использовал именно их. С++ - это не только язык. В него входит также и стандартная библиотека. Везде, где возможно, вместо указателей char* в книге использован стандартный тип string, и я призываю вас поступать также. Применение объектов string не создает дополнительных трудностей по сравнению со строками, обработка которых производится с помощью указателей char*, но значительно облегчает управление памятью. Кроме того, когда используются объекты string, снижается риск утечек памяти при возникновении исключений (см. правила 9 и 10). Хорошо реализованный тип string по эффективности не уступит своему эквиваленту char*, а, возможно, и превзойдет его (чтобы понять, как это сделать, см. правило 29). Если стандартный тип string не реализован в вашем компиляторе, то в нем почти наверняка реализован какой-либо класс, подобный string. Обязательно используйте его. Это всегда предпочтительней, чем включение в код указателей char*. В книге при любой возможности используются структуры данных, взятые из Standard Template Library (STL - стандартная библиотека шаблонов, см. правило 35). STL содержит битовые наборы, векторы, списки, очереди, стеки, карты, множества и т.д., и лучше иметь дело со стандартизованными объектами, чем пытаться разработать их эквиваленты самостоятельно. В состав ваших компиляторов STL может быть не включена, но благодаря компании Silicon Graphics бесплатная копия библиотеки доступна на Web-сайте SGISTL: http: www.sgi.com/ Technology/STL/. Если вы довольны используемой вами в настоящее время библиотекой алгоритмов и структур данных, то не нужно переходить на STL только потому, что она стандартная . Однако если вы стоите перед выбором, взять ли компонент из STL или написать какой-либо код самому с нуля , то вариант с STL, конечно, предпочтительнее. Помните о принципе повторного применения кода? STL (и остальная часть стандартной библиотеки) содержит множество модулей, которые очень и очень стоит использовать повторно. Соглашения и терминология Когда в книге упоминается наследование, я всегда имею в виду открытое наследование. Использование закрытого наследования каждый раз оговаривается Рис. 1 Эта запись обратна той, которую я использовал в первом (но не во втором) издании книги Эффективное использование С++ . Теперь я убежден, что большинство пользователей С++ проводят стрелки наследования от производного класса к базовому, и с удовольствием соглашаюсь с ними. На диаграммах подобного типа абстрактные классы (например, GameObj ect (Игровой объект)) закрашены темно-серым цветом, а конкретные классы (такие как Spaceship (Космический корабль)) заштрихованы более светлым оттенком. Наследование автоматически приводит к появлению указателей и ссылок двух различных типов: статического и динамического. Статический тип указателя или ссылки соответствует типу объявления. Динамический тип - типу объекта, на который в данный момент указывает указатель или ссылка. Вот несколько примеров, основанных на приведенных выше классах: GameObj ect *pgo = new Spaceship; Asteroid *pa = new Asteroid; pgo = pa; GameObjectSc rgo = *pa; Статический типpgo- GameObj ect,динамический тип - Spaceship*. Статический тип pa - Asteroid* . / / Динамический тип - тоже Asteroid*. Статический типpgo не изменился (ине изменится) , он по-прежнему равен GameObject*. Его динамический тип теперь - Asteroid* . Статический тип rgo- GameObj ect,динамический тип - Asteroid. Эти примеры также демонстрируют соглашение об именах переменных, используемое в этой книге. Переменная pgo - это указатель на GameObj ect, специально. При изображении иерархии наследования стрелки проводятся от производных классов к базовому. Например, на рис. 1 приведена иерархия классов для правила 31: В других книгах вы можете встретить иные варианты перевода английских понятий window handle и database lock, поскольку в русском языке компьютерная терминология еще недостаточно устоялась. Обычно программисты обобщенно называют эти инструменты хэндлами (от англ. handle). (Прим. ред.) pa - указатель на Asteroid, rgo - ссылка на GameObject. Я часто составляю имена переменных и ссылок подобным образом. Два моих любимых имени для параметров - это Ihs и rhs, сокращения для слева (left-hand side) и справа (right-hand side) соответственно. Чтобы понять, что стоит за этими именами, рассмотрим класс для представления действительных чисел: Class Rational{......} ; Функция для попарного сравнения объектов класса Rational может быть объявлена следующим образом: bool operator== (const RationalSc Ihs, const Rational&rhs) ; Такое объявление позволяет писать программы следующим образом: Rational г1, г2 ; if {г1==г2) . . . В операторе сравнения г1 стоит слева от оператора == и соответствует аргументу Ihs при вызове operator==, г2 расположено справа от оператора = = и соответствует аргументу rhs. Другие сокращения, использованные в этой книге: ctor обозначает конструктор (constructor), dtor - деструктор (destructor), RTTI - динамическое определение типов в С++ (оператор dynamic cast - наиболее часто используемый компонент этого механизма). Если выделить память, а затем не освободить ее, то происходит утечка памяти. Утечки могут возникать как в С, так и в С++, но в последнем они приводят к более серьезным последствиям. Это связано с тем, что в С++ при создании объектов автоматически вызываются конструкторы, которые могут сами выделять ресурсы. Посмотрите на этот пример: classWidget {......}; Некий класс - неважно, что он делает. Widget *pw = new Widget; Динамическое выделение / / памяти под объект Wi dge t. ... Предположим, что область, / / на которую указывает pw, / / никогда не освобождается. Этот код вызывает утечку памяти, потому что объект Widget, на который указывает переменная pw, никогда не будет удален. Возможна ситуация, когда конструктор Widget потребует выделения дополнительных ресурсов (таких как дескрипторы, семафоры, манипуляторы окон, блокираторы баз данных* и т.п.).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |