Рекомендации по программированию

· При создании класса следует хорошо продумать его интерфейс – средства работы с классом для тех программ, которые будут его использовать. Интерфейс должен быть интуитивно понятным и включать только методы. Поля данных класса должны быть скрытыми.

· Не следует определять методы типа get/set для всех скрытых полей класса — это все равно, что открыть к ним доступ, только более сложным способом. Поля класса вводятся только для того, чтобы реализовать свойства класса, представленные в его интерфейсе с помощью методов.

· Не нужно расширять интерфейс класса без необходимости, «на всякий случай», поскольку увеличение количества методов ведет к трудности понимания класса пользователем. В идеале интерфейс должен быть полным, то есть предоставлять возможность выполнить любые разумные действия с классом, и минимальным — без дублирования и пересечения возможностей методов.

· В виде методов рекомендуется определять только действия, реализующие свой­ства класса. Если какое-либо действие можно реализовать, не обращаясь к скры­тым полям класса, его нет необходимости описывать как метод; лучше описать его как обычную функцию, поместив ее в общее с классом пространство имен. Если функция выполняет действие, не являющееся свойством класса, но нуж­дается в доступе к его скрытым полям, ее следует объявить как дружественную. Но в общем случае дружественных функций и классов надо избегать, поскольку главной идеей ООП является минимизация связей между инкапсулированными классами.

· Для увеличения производительности программы наиболее часто вызываемые методы можно объявить как встроенные (inline). В основном это касается корот­ких методов, тело которых оказывается меньше размера кода, генерируемого для их вызова. Кроме ускорения программы за счет исключения вызовов, это дает возможность компилятору производить более полную оптимизацию. Однако не­обходимо учитывать, что директива inline носит для компилятора рекоменда­тельный характер.

· Конструкторы и деструкторы делать встраиваемыми не рекомендуется, посколь­ку в них фактически присутствует код, помещаемый компилятором, размер этого кода может быть весьма значительным (например, в конструкторе произ­водного класса должны быть вызваны конструкторы всех базовых и вложенных классов).

· Перегруженные операции класса должны иметь интуитивно понятный общепри­нятый смысл (например, не следует заставлять операцию + выполнять что-либо, кроме сложения или добавления).

· Если какая-либо операция перегружена, следует, если возможно, перегрузить и аналогичные операции, например, +, += и ++ (компилятор этого автоматически не сделает). При этом операции должны иметь ту же семантику, что и их стандарт­ные аналоги.

· И конструктор копирования, и операция присваивания, создаваемые по умол­чанию, выполняют поэлементное копирование из области-источника в об­ласть-приемник. Если объект содержит указатели, это приведет к тому, что после копирования два соответствующих указателя разных объектов будут ссылаться на одну и ту же область памяти. При уничтожении первого из объектов эта па­мять будет освобождена, а повторная попытка освободить ее при уничтожении второго объекта приведет к неопределенному поведению программы. Поэтому для классов, содержащих поля-указатели, следует всегда явно определять конст­руктор копирования и операцию присваивания, выполняющие выделение памя­ти под динамические поля объекта.

· Динамическая память, выделенная в конструкторе объекта, должна освобождаться в его деструкторе. Невыполнение этого требования приводит к утечкам памяти. Удаление нулевого указателя безопасно (при этом ничего не происходит), поэтому если конструкторы, конструкторы копирования и опера­ция присваивания написаны правильно, любой указатель либо ссылается на вы­деленную область памяти, либо равен нулю, и к нему можно применять delete без проверки.

· Разница между конструктором копирования и операцией присваивания заклю­чается в том, что последняя работает в том случае, когда объект-приемник уже существует, поэтому в ней перед выделением динамической памяти следует ос­вободить память занятую ранее. Из этого следует, что при реализации операции при­сваивания для классов, содержащих поля-указатели, необходимо проводить про­верку на самоприсваивание и в этом случае оставить объект без изменений. Необходимо также помнить о том, что операция присваивания должна возвра­щать ссылку на константу.

· В конструкторах для задания начальных значений полям рекомендуется исполь­зовать инициализацию, а не присваивание. Инициализация более универсальна, так как может применяться в тех случаях, когда присваиванием пользоваться нельзя (например, при задании значений константным полям или ссылкам). Кроме того, она выполняется более эффек­тивно, потому что создание объекта в C++ начинается с инициализации его по­лей конструктором по умолчанию, после чего выполняется вызываемый конст­руктор. Необходимо учитывать и тот факт, что поля инициализируются в порядке их объ­явления, а не в порядке появления в списке инициализации. Поэтому для умень­шения числа возможных ошибок порядок указания полей в списке инициализа­ции конструктора должен соответствовать порядку их объявления в классе.

· Статические поля не должны инициализироваться в конструкторе, поскольку им нужно присваивать начальное значение только один раз для каждого класса, а конструктор выполняется для каждого объекта класса. Статические поля ини­циализируются в глобальной области определения (вне любой функции).

· Конструкторы копирования также должны использовать списки инициализации полей, поскольку иначе для базовых классов и вложенных объектов будут вызва­ны конструкторы по умолчанию.

· Операция присваивания не наследуется, поэтому она должна быть определена в производных классах. При этом из нее следует явным образом вызывать соответ­ствующую операцию базового класса

· Открытое наследование класса Y из класса X означает, что Y представляет со­бой разновидность класса X, то есть более конкретную, частную концепцию. Ба­зовый класс X является более общим понятием, чем Y. Везде, где можно ис­пользовать X, можно использовать и Y, но не наоборот (вспомните, что на место ссылок на базовый класс можно передавать ссылку на любой из производных). Необходимо помнить, что во время выполнения программы не существует иерархии классов и передачи сообщений объектам базового класса из производ­ных — есть только конкретные объекты классов, поля которых формируются на основе иерархии на этапе компиляции.

· Методы, которые должны иметь все производные классы, но которые не могут быть реализованы на уровне базового класса, должны быть виртуальными. На­пример, все объекты иерархии должны уметь выводить информацию о себе. По­скольку она хранится в различных полях производных классов, эту функцию нельзя реализовать в базовом классе. Естественно назвать ее во всех классах оди­наково и объявить как виртуальную с тем, чтобы другие методы базового класса могли вызывать ее в зависимости от фактического типа объекта, с которым они работают. По этой причине деструкторы объявляются как виртуальные.

· При переопределении виртуальных методов нельзя изменять наследуемое значе­ние аргумента по умолчанию, поскольку по правилам C++ оно определяется ти­пом указателя, а не фактическим типом объекта, вызвавшего метод.

6. Среда программирования Visual C++ 6.0

Общий вид окна

Проект (project) – это набор файлов, которые совместно используются для создания одной программы.

Рабочее пространство (workspace) может включать в себя несколько проектов.

 

После запуска VC++ 6.0 на экране появится окно (рис. 1).

Окно содержит:

· Главное меню (1) – список основных команд VC++;

· Панель инструментов (2) - панель с кнопками команд Visual C++;

· Панель рабочего пространства Workspace (3) - содержит две вкладки:

- ClassView – отображает список классов в проекте,

- FileView – отображает список файлов, входящих в проект.

· Окно для редактирования кодов (4) – окно с текстом программы;

· Выходную панель результатов компиляции (5) - окно для вывода сообщений в процессе компиляции или отладки, показывает текущую стадию компиляции, список ошибок и предупреждений и их количество.

 

Рис. 1. Окно VC++ 6.0.

Создание консольного приложения и работа с ним

Консольное приложение – это приложение, которое с точки зрения программиста является программой DOS, но может использовать всю доступную оперативную память (если каждый элемент данных программы не будет превышать 1 Мб). Этот тип приложения запускается в особом окне, которое называется “Окно MS-DOS”. На примере консольных приложений прослеживаются этапы развития VC++ при переходе от одной версии к другой.

Каждое приложение, разрабатываемое как отдельный проект в среде VC++6.0, нуждается в том, чтобы ему соответствовало свое собственное рабочее пространство. Рабочее пространство включает в себя те папки, в которых будут храниться файлы, содержащие информацию о конфигурации проекта. Для того чтобы создать новое пространство для проекта, надо выполнить следующие действия:

1. В линейке меню нажать на меню File.

2. Выбрать пункт New или нажать Ctrl+N.

3. Появится окно New. В нем содержится четыре вкладки: Files, Projects, Workspaces, Other Documents. Выбрать вкладку Projects.

4. Из списка возможных проектов выбрать Win32 Console Application для создания приложения DOS.

5. В поле Project name ввести имя проекта.

6. В поле Location ввести путь для размещения каталога проекта, или, нажав на кнопку справа […], выбрать нужную директорию.

7. Должен быть установлен флажок Create New Workspace. Тогда будет создано новое рабочее окно. Нажать кнопку OK

8. Установить один из флажков:

- An empty project – создается пустой проект, не содержащий заготовок для файлов;

- A simple application – создается простейшая заготовка, состоящая из заголовочного файла StdAfx.h, файла StdAfx.cpp и файла реализации;

- A “Hello World” application и An application that supports MFC являются демонстрационными и разными способами демонстрируют вывод на экран строки символов.

Нажать кнопку Finish. Появитсяинформация о созданном проекте содержащая: тип проекта, некоторые особенности и директорию.

После создания проекта в него необходимо записать код программы. При этом можно создать новый файл или добавить в проект существующий файл.

Для создания нового файла надо выполнить следующие действия:

  1. Выбрать меню File > New или Project > Add to Project > New.
  2. Открыть вкладку Files.
  3. Выбрать C++ Source File.
  4. Чтобы создаваемый файл был автоматически присоединен к проекту, необходимо установить флаг Add to project.
  5. В поле Filename ввести имя файла.
  6. В поле Location указать путь для создания файла.
  7. Нажать OK.

Для добавления существующего файла надо:

1. Выбрать в меню File > Add to Project > Files

2. Указать полное имя файла, который нужно присоединить

Для открытия существующего проекта надо:

1. Выбрать меню File > Open Workspace

2. Указать файл с расширением .dsw

Для сохранения текущего проекта надо выбрать в главном меню File > Save Workspace.

Для закрытия текущего проекта надо выбрать в главном меню File > Close Workspace.

После создания или открытия проекта в окне Workspace появится или список классов, или список файлов входящих в проект. В зависимости от типа проекта, он будет или пустой, или содержать изначально некоторые файлы, присущие данному типу. Проект приложения для DOS изначально пустой. В него можно добавить новые файлы или присоединить уже существующие.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: