Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование. Оформление лаб.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.42 Mб
Скачать

Сохранение настроек

Сохранить настройку пакета Doxygen можно с помощью меню

Settings/User current settings at startup

Е.4 ИСПОЛЬЗОВАНИЕ

1) Создать проект Visual C++.

2) Подготовить и сохранить исходный код в файлах .cpp и .h. При подготовке исходного кода использовать специальный вид комментариев (см. приложение А).

3) Выполнить обработку файлов с исходным кодом пакетом Doxygen:

– вызвать мастер DoxywizardVisual Studio: меню Tools / doxyWizard или клавиши Alt+T, Z. В Eclipse: меню Run / External Tools / doxy);

– активировать Doxygen (закладка Run, кнопка Run doxygen);

– дождаться сообщения "Doxygen has finished" в окне "Output produced by doxygen".

4) Проверить результат – кнопка Show HTML output.

Примечание: Результат работы Doxygen сохраняется в папке html текущего каталога проекта (использовать файл index.html).

Е.5 РЕКОМЕНДАЦИИ ПО КОММЕНТИРОВАНИЮ

1) Комментарии для Doxygen располагают непосредственно перед введением имён – объявлением классов, их полей, методов, а так же функций, переменных, констант и т.д. Комментарии в JavaDoc стиле:

/**

* Краткий комментарий.

* Подробное описание

*/

или

/// Краткий комментарий.

Можно приводить комментарии в той же строке, что и комментируемое выражение:

int var; /**< Текст комментария. */

или

int var; ///< Текст комментария.

2) Код реализации методов и функций комментируется в обычном C++ стиле.

3) Каждый файл проекта начинается с заголовка:

/**

* @file FileName.ext

* Назначение данного файла.

* @author имя

* @version х.y.z

* @date yyyy.mm.dd

*/

Примечание: возможные варианты комментирования исходного кода, обрабатываемые системой Doxygen, подробно рассмотрены в C:\Program Files\doxygen\html\docblocks.html

Е.6 ПРИМЕР КОММЕНТИРОВАНИЯ

Е.6.1 Пример комментирования объявления класса

(файл One.h)

/**

* @file One.h

* Объявление класса One.

* @author xone

* @version 0.0.1

* @date 2015.09.01

*/

#ifndef ONE_H_

#define ONE_H_

/**

* Предназначен для демонстрации автодокументирования класса.

* Используются комментарии в стиле Javadoc для обработки пакетом Doxygen

*/

class One {

public:

/**

* Инициализация полей.

* Используется список инициализации, тело - пустое

*/

One();

/**

* Пустой деструктор.

*/

virtual ~One();

/**

* Установка поля One::x.

* @param x присваивается полю One::x

*/

void setX(int x);

/**

* Чтение поля One::x.

* @return текущее значение поля One::x

*/

int getX() const;

private:

/** Используется для демонстрации краткого комментария аттрибута. */

int x;

};

#endif /* ONE_H_ */

Е.6.2 Пример комментирования реализации класса

(файл One.cpp)

/**

* @file One.cpp

* Реализация класса One.

* @author xone

* @version 0.0.1

* @date 2015.09.01

*/

#include "One.h"

One::One() : x(-1) {

// Пустое тело.

}

One::~One() {

// Пустое тело.

}

int One::getX() const {

return x;

}

void One::setX(int x) {

// Используем this для доступа к аттрибуту.

this->x = x;

}

Е.6.3 Пример комментирования объявления и реализации функции

(файл main.cpp)

/**

* @file main.cpp

* Реализация функции main().

* @author xone

* @version 0.0.1

* @date 2015.09.01

*/

#include "One.h"

/**

* Точка входа.

* @param argc количество параметров командной строки

* @param argv массив параметров командной строки

* @return код завершения

*/

int main(int argc, char** argv) {

// Обычные комментарии C++.

// ...

return 0;

}

Е.6.4 Пример комментирования объявления перегруженного оператора

/**

* Вывод экземпляров One и его потомков в стандартный поток.

* Для вывода в поток используется виртуальный метод,

* вызываемый через ссылку на базовый класс (полиморфизм)

* @param os ссылка на поток вывода

* @param one ссылка на выводимый объект

* @return ссылка на поток вывода

* @remark Пример перегрузки оператора для базового класса,

* который используется и для его потомков

* @see One

*/

ostream& operator<<(ostream& os, One& one);

Е.7 ПРИМЕР ИСПОЛЬЗОВАНИЯ DOXYGEN ДЛЯ СОЗДАНИЯ UML ДИАГРАММ

На рис. Е.x приведен пример диаграммы связей, полученной в результате обработки системой Doxygen следующего текста:

class Invisible { };

class Truncated : public Invisible { };

class Undocumented { };

class PublicBase : public Truncated { };

template<class T> class Templ {};

class ProtectedBase { };

class PrivateBase { };

class Used { };

class Inherited : public PublicBase, protected ProtectedBase,

private PrivateBase, public Undocumented, public Templ<int> {

private:

Used *m_usedClass;

};

Рисунок Е.x – Диаграмма связей. Сгенерирована системой Doxygen

Е.8 КОМАНДЫ СИСТЕМЫ DOXYGEN

Команды располагаются в теле комментариев, оформленных указанным выше способом, и начинаются с символа @ (at-sign) или \ (backslash).

@author author_name

Автор кода (ФИО студента / группа, сдающего работу)

@date xx.xx.xx

Дата начала реализации работы

@file file_name.ext Описание

Указывает на то, что документируется файл

с исходным кодом по имени "file_name.ext"

@param param_name Описание

Описание параметра функции или метода. Имя параметра – "param_name". Можно указать направление параметра атрибутами [in], [in,out] или [out], например, @param[out] ...

@remark Текст примечания

Содержит текст примечания

@return Описание

Описание возвращаемого результата

@see references

Перекрестная ссылка. Несколько ссылок можно разделять символом |

@throw <exception_object> Описание

Описание выбрасываемого исключения

@version version_info

Информация о версии работы (в рамках обучения версия всегда может равняться 1.0)

Примечание: полная справка по командам системы Doxygen находится в

C:\Program Files\doxygen\html\commands.html

ДОДАТОК Ж

ПРАВИЛА КОДУВАННЯ (CODE-CONVENTION)

  1. Имя сущности должно отражать её назначение, исключая двусмысленность.

  2. Все имена следует записывать по-английски

fileName; // НЕ РЕКОМЕНДУЕТСЯ: imyaFayla

  1. Следует избегать "магических" чисел в коде.

Числа, отличные от 0 или 1, следует объявлять, как именованные константы или создавать метод для доступа к константе.

  1. Именованные константы (включая значения перечислений) должны быть записаны в верхнем регистре с нижним подчёркиванием в качестве разделителя (ALL_CAPITALS_CASE)

MAX_ITERATIONS, COLOR_RED, PI

  1. Названия пространств имён следует записывать в нижнем регистре

model::analyzer, io::iomanager, common::math::geometry

  1. Имена типов должны быть записаны в смешанном регистре, начиная с верхнего (UpperCamelCase)

Line, SavingsAccount

  1. Имена типов в шаблонах следует называть одной заглавной буквой

template<class T>

//...

template<class C, class D>

//...

  1. Имена переменных должны быть записаны в смешанном регистре, начиная с нижнего (lowerCamelCase)

line, savingsAccount

  1. Аббревиатуры и сокращения в именах должны записываться в нижнем регистре

exportHtmlSource(); // НЕЛЬЗЯ: exportHTMLSource();

openDvdPlayer(); // НЕЛЬЗЯ: openDVDPlayer();

  1. Переменным пользовательских типов в общем случае следует давать то же имя, что и у их типа

void setTopic(Topic* topic) // НЕ РЕКОМЕНДУЕТСЯ: void setTopic(Topic* value)

// НЕ РЕКОМЕНДУЕТСЯ: void setTopic(Topic* aTopic)

// НЕ РЕКОМЕНДУЕТСЯ: void setTopic(Topic* t)

void connect(Database* database) // НЕ РЕКОМЕНДУЕТСЯ: void connect(Database* db)

// НЕ РЕКОМЕНДУЕТСЯ: void connect (Database* oracleDB)

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

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

Point startingPoint, centerPoint;

Name loginName;

  1. Для представления наборов (коллекций) объектов следует использовать множественное число

vector<Point> points;

int values[];

  1. Переменные, имеющие большую область видимости, следует называть длинными именами, а небольшую – короткими.

  2. Имена переменных для хранения временных значений или индексов в пределах нескольких строк кода следует делать короткими. Обычно это переменные i, j, k, l, m, n для целых, а также c и d для символов.

  3. Использования глобальных переменных следует избегать.

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

::mainWindow.open(), ::applicationContext.getName()

::getMaxWindowWidth()

  1. Названия функций и методов должны быть записаны в смешанном регистре и начинаться с нижнего (lowerCamelCase)

getName(), computeTotalWidth()

  1. Слова get/set должны быть использованы везде, где осуществляется прямой доступ к атрибуту

employee.getName();

employee.setName(name);

matrix.getElement(2, 4);

matrix.setElement(2, 4, value);

  1. Префикс is следует использовать только для булевых (логических) переменных и методов

isSet, isVisible, isFinished, isFound, isOpen

  1. В некоторых ситуациях префикс is лучше заменить на другой: has, can или should

bool hasLicense();

bool canEvaluate();

bool shouldSort();

  1. Нельзя давать булевым (логическим) переменным имена, содержащие отрицание

bool isError; // НЕЛЬЗЯ: isNoError или noError

bool isFound; // НЕЛЬЗЯ: isNotFound или notFound

  1. Комментарии к функциям и методам следует давать при объявлении в соответствии с соглашениями JavaDoc.

  2. Использовать const следует везде, где это имеет смысл:

  • при объявлении параметров функции (метода), если функция (метод) не изменяет данные, передаваемые по ссылке или через указатель;

  • при объявлении методов везде, где это возможно (аксессоры всегда должны быть const);

  • при объявлении переменных, которые не изменяются после конструирования.

  1. Инициализировать переменные лучше при объявлении. Если инициализация при объявлении невозможна или не имеет смысла, то лучше оставить переменные неинициализированными, чем присваивать им какие-либо значения

int x, y, z;

getCenter(&x, &y, &z);

  1. Приведение типов должно быть явным. Приведения типов в стиле языка C следует избегать

floatValue = static_cast<float>(intValue);

// НЕ РЕКОМЕНДУЕТСЯ: floatValue = intValue;

// НЕЛЬЗЯ: floatValue = (float)intValue;

  1. Пробелы и отступы следует использовать для улучшения читабельности:

  • операторы следует отбивать пробелами;

  • после зарезервированных ключевых слов языка C++ следует ставить пробел;

  • после запятых следует ставить пробелы;

  • в списках инициализации конструкторов двоеточие следует отбивать пробелами;

  • после точек с запятой в цикле for следует ставить пробелы.

Основной отступ – табуляция (четыре пробела).

a = (b + c) * d; // НЕ РЕКОМЕНДУЕТСЯ: a=(b+c)*d;

while (true) { // НЕ РЕКОМЕНДУЕТСЯ: while(true){

doSomething(a, b, c, d); // НЕ РЕКОМЕНДУЕТСЯ: doSomething(a,b,c,d);

SomeClass::SomeClass() : // НЕ РЕКОМЕНДУЕТСЯ: SomeClass::SomeClass():

for (i = 0; i < 10; i++) { // НЕ РЕКОМЕНДУЕТСЯ: for(i=0;i<10;i++){

  1. Логически связанные блоки в коде следует отделять пустой строкой и/или строкой с поясняющими комментариями

Matrix4x4 matrix = new Matrix4x4();

// Пояснения...

double cosAngle = Math.cos(angle);

double sinAngle = Math.sin(angle);

// Пояснения...

matrix.setElement(1, 1, cosAngle);

matrix.setElement(1, 2, sinAngle);

matrix.setElement(2, 1, -sinAngle);

matrix.setElement(2, 2, cosAngle);

// Пояснения...

multiply(matrix);

  1. Циклы следует оформлять следующим образом

for (initialization; condition; update) {

//...

}

while (condition) {

//...

}

do {

//...

} while (condition);

  1. Циклов с пост-условием do-while следует избегать.

  2. Для бесконечных циклов следует использовать форму while (true).

  3. Выражения, не относящиеся к управлению циклом, в конструкцию for включать нельзя

sum = 0; // НЕЛЬЗЯ:

for (i = 0; i < n; i++) { // for (i = 0, sum = 0; i < n; i++) {

sum += value[i]; // sum += value[i];

} // }

  1. Переменные, относящиеся к циклу, следует инициализировать непосредственно передним

isDone = false; // НЕ РЕКОМЕНДУЕТСЯ:

while (!isDone) { // bool isDone = false;

//... // ...

} // while (!isDone) {

// ... // }

  1. Конструкцию if-else следует оформлять следующим образом

if (condition) {

//...

} else if (condition) {

//...

} else {

//...

}

  1. Условие следует размещать в отдельной строке

if (isDone) { // НЕ РЕКОМЕНДУЕТСЯ: if (isDone) doCleanup();

doCleanup();

}

  1. Сложных условных выражений следует избегать. Лучше вместо этого использовать булевы переменные

bool isFinished = (elementNo < 0) || (elementNo > maxElement);

bool isRepeatedEntry = elementNo == lastElement;

if (isFinished || isRepeatedEntry) {

//...

}

// НЕ РЕКОМЕНДУЕТСЯ:

// if ((elementNo < 0) || (elementNo > maxElement)||

// elementNo == lastElement) {

// ...

// }

  1. Исполняемых выражений в условиях следует избегать

File* fileHandle = open(fileName, "w");

if (!fileHandle) {

//...

}

// НЕ РЕКОМЕНДУЕТСЯ:

// if (!(fileHandle = open(fileName, "w"))) {

// ...

// }

  1. Конструкцию switch следует оформлять следующим образом

switch (condition) {

case 1:

//...

// Отсутствует "break"

case 2:

//...

break;

case 3:

//...

break;

default:

//...

break;

}

Если где-то отсутствует ключевое слово break, то следует предупреждать об этом в комментарии.

  1. Конструкцию try-catch следует оформлять следующим образом

try {

//...

} catch (Exception &exception) {

//...

}

  1. Объявления классов следует оформлять следующим образом

class SomeClass: public BaseClass {

public:

SomeClass();

virtual ~SomeClass();

//...

protected:

//...

private:

//...

};

Вначале объявляются друзья (вне какого-либо раздела). Разделы класса public, protected и private должны быть явно указаны, сгруппированы и следовать в данном порядке.

  1. Статические элементы должны объявляться вначале своего раздела.

  2. Не следует объявлять переменные класса (поля, атрибуты) как public. Если это необходимо – используйте структуры.

  3. Использование структур следует избегать – ухудшает читаемость кода.

  4. Комментарии к классам, полям и методам следует делать при объявлении в соответствии с соглашениями JavaDoc.

  5. Определение (реализацию) методов следует оформлять следующим образом

SomeClass::SomeClass() :

someField(0) {

//...

}

void SomeClass::someMethod() {

//...

}

  1. Заголовочные (.h) файлы объявляют интерфейс, файлы исходного кода (.cpp) его реализовывают. Заголовочным (включаемым) файлам следует давать расширение h (рекомендуется) либо hpp. Файлы исходных кодов (компилируемые) могут иметь расширения cpp (рекомендуется), C, cc либо c++. Класс следует объявлять в заголовочном (.h) файле и определять (реализовывать) в компилируемом (.cpp) файле.

  2. Имя файла должно совпадать с именем класса.

MyClass.h, MyClass.cpp

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

  1. Заголовочные файлы должны содержать защиту от повторного включения

#ifndef FILENAME_H

#define FILENAME_H

//...

#endif

  1. Заголовочные файлы не должны содержать директиву using namespace.

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

  • собственный заголовочный файл;

  • дополнительные заголовочные файлы;

  • системные заголовочные файлы.