Личный опыт разработки ПО

Сборник рецептов

Boost Optional

Прокомментировать

В C# при объявлении переменной можно приставить знак вопроса, после чего в дальнейшем проверять была ли переменная инициализирована или нет:

int? a;
...
if (a.HasValue)
{
	...
}

Иногда это бывает очень полезно, например при работе с базами данных.

В C++ к сожалению такого удобства нет, но как известно – программисты C++ отличаются верностью и если язык не предоставляет какую либо возможность, они ее добавляют сами. Например в Boost данный функционал присутствует:

#include <boost/optional.hpp>
...
boost::optional<int> a;
std::cout << (a.is_initialized() ? "Есть значение" : "Нет значения") << std::endl;
boost::optional<int> b(3);
std::cout << (b ? "Есть значение" : "Нет значения") << std::endl;
a = 5;
std::cout << (a ? "Есть значение" : "Нет значения") << std::endl;
int result = a.get() + b.get();
std::cout << result << std::endl;
b.reset();
std::cout << (b ? "Есть значение" : "Нет значения") << std::endl;

Вывод:

Нет значения
Есть значение
Есть значение
8
Нет значения

20th Февраль 2010
22:45

Рубрика: C++

Метки: ,


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

комментариев 14

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

Что такое Doxygen?

Doxygen – это кроссплатформенная система документирования кода с поддержкой языков C++, C, Java, Objective-C, PHP, C# (список можно уточнить на сайте проекта).

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

Doxygen умеет анализировать исходный код проекта и создавать удобную документацию в формате HTML, Latex, RTF, XML, man, CHM.

Общие соображения

  1. Написание документации должно быть максимально простым, чтобы разработчики не "забывали" это делать. Отсюда вывод, что сложность форматирования комментариев должна быть минимальной.

    Хорошо:

    namespace A
    {
    /**
    Имя класса
     
    Описание класса
    */
    	class B
    	{
    	};
    }

    Плохо:

    namespace A
    {
    	/**
    	 * Имя класса
    	 * 
    	 * Описание класса
    	 */
    	class B
    	{
    	};
    }

    Почему второй вариант хуже? Очевидно, из-за необходимости выравнивать комментарии на одном уровне с комментируемой сущностью, а также из-за избыточных символов *. Это может показаться надуманным, но при написании комментариев из нескольких строк проблема проявляется, а при поддержке кода и вовсе становится кошмаром. Вы можете возразить, что подобный стиль делает код "рваным", но в любом случае комментирование интерфейсов делает код менее читаемым. К счастью все современные редакторы кода позволяют легко свернуть блоки с комментариями, что позволит взглянуть на код без помех.

  2. Много документации – плохо, так как мало кто будет читать длинные мануалы. Из этого следует, что документированы должны быть только открытые (public) и защищенные (protected) интерфейсы. Закрытые (private) интерфейсы – часть внутренней реализации и не должны быть в руководстве.

Читать заметку полностью »

7th Февраль 2010
23:00


Скорость CMake

комментария 2

Некоторые интересуются, а как же у CMake со скоростью? Субъективно все достаточно быстро, если же говорить о цифрах, то один из разработчиков Quantum GIS приводит в своем блоге сравнение скорости сборки их проекта с CMake и с Autotools. Цифры конечно впечатляют – так хорошо, что даже странно. Смотрите сами:

http://blog.qgis.org/?q=node/16

3rd Февраль 2010
20:33

Рубрика: Разработка,Сборка

Метки:


Определение операционной системы с CMake

Прокомментировать

Часто при сборке кроссплатформенного приложения необходимо знать на какой платформе выполняется сборка. Это нужно для включения определенных файлов специфичных для конкретной платформы, например средства межпроцессного взаимодействия для Linux или для Windows.

Для определения типа платформы существует несколько переменных:

  • UNIX – системы соответствующие стандарту POSIX (например Linux, FreeBSD или MAC OS X), включает CygWin
  • WIN32 – понятно без комментариев

Зная это легко проделать нужные действия:

if (WIN32)
	set (SOURCES ${SOURCES} win_pipe.cpp)
elseif (UNIX)
	set (SOURCES ${SOURCES} posix_pipe.cpp)
else ()
	message (FATAL_ERROR "Неизвестная система")
endif ()

Обратите внимание, что команда message с ключом FATAL_ERROR выводит сообщение и прекращает выполнение работы.

Иногда этого бывает мало и необходимо точно определить тип системы или даже дистрибутив и его версию. Для этих целей можно использовать переменную CMAKE_SYSTEM:

if (${CMAKE_SYSTEM} MATCHES "Linux")
	message ("Linux")
	if (${CMAKE_SYSTEM} MATCHES "fc8")
		message ("Fedora 8")
	endif ()
elseif (${CMAKE_SYSTEM} MATCHES "FreeBSD")
	message ("FreeBSD")
elseif (${CMAKE_SYSTEM} MATCHES "Darwin")
	message ("Mac OS X")
endif ()

Полный список полезных переменных можно посмотреть в Kitware Public Wiki.

1st Февраль 2010
21:29

Рубрика: Разработка,Сборка

Метки:


Освобождение памяти занятой контейнером

комментария 3

На днях объяснял товарищу, что у std::vector метод clear(), хоть и удаляет свое содержимое, но вот выделенную память не возвращает. Например, после запуска следующей программы:

#include <iostream>
#include <vector>
 
int main(int argc, char* argv[])
{
	std::vector<int> data;
	data.resize(200000);
	std::cout << data.capacity() << std::endl;
	data.clear();
	std::cout << data.capacity() << std::endl;
	return 0;
}

Будет выведено:

200000
200000

Почему не возвращает? Потому, что есть метод resize и reserve, которые резервируют память и поэтому освободить память было бы крайне некорректно по отношению к ним.

Что же делать? Не паниковать, а после удаления содержимого использовать следующую идиому:

std::vector<int>().swap(data);

Также может быть полезным освободить незанятую память, например после удаления доброй половины большого контейнера:

std::vector<int>(data).swap(data);

24th Январь 2010
21:55

Рубрика: C++

Метки:


Boost Test, юнит-тестирование и CMake

комментариев 10

Boost Test

Написанием модульных тестов можно не только повысить скорость разработки за счет экономии времени на отладке, но и повысить качество. Также написание тестов позволяет критично взглянуть на интерфейсы классов и функций, что выливается в создание простых и логичных интерфейсов. Но разработка с применением тестов может не принести ощутимых плодов из-за сложности написания тестов, что выльется в слабое покрытие кода тестами. Поэтому инструмент для тестирования должен быть максимально простым, написание тестов должно происходить с приложением минимального количества усилий. Я пользовался фреймворком для написания тестов UnitTest++ – это очень хороший и удобный инструмент и если вы не используете Boost, я бы порекомендовал обратить на него пристальное внимание. Но в данной заметке речь пойдет не о нем, а о фреймворке Boost Test.

Читать заметку полностью »

24th Январь 2010
19:09


CMake и Boost

комментариев 10

В этой заметке я хочу рассмотреть тему сборки проектов использующих библиотеки Boost. Мы рассмотрим проект из исполняемого файла использующего Boost Thread и двух библиотек использующих Boost Unit Test Framework.

Первым делом необходимо установить значения переменных отвечающих за тип линковки библиотек (статическая или динамическая):

set (Boost_USE_STATIC_LIBS ON)

И использование многопоточности библиотеками:

set (Boost_USE_MULTITHREADED ON)

После этого можно выполнить уже знакомую по заметке о CMake и QT команду find_package:

find_package (Boost COMPONENTS список_нужных_модулей REQUIRED)

Дополнительно можно указать необходимую версию Boost:

find_package (Boost 1.35.0 COMPONENTS список_нужных_модулей REQUIRED)

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

include_directories(${Boost_INCLUDE_DIRS})
...
target_link_libraries (${PROJECT} ${Boost_LIBRARIES})

Читать заметку полностью »

23rd Январь 2010
18:48

Рубрика: Разработка,Сборка

Метки: ,


CMake и Qt

комментариев 28

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

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

Читать заметку полностью »

16th Январь 2010
18:36

Рубрика: Разработка,Сборка

Метки: ,


Сборка проектов с CMake. Введение

комментариев 13

Для автоматизации сборки проектов традиционно используют системы сборки, такие как make на Unix подобных системах и nmake для компилятора Microsoft. Также традиционно написание файлов для сборки проекта под эти системы является задачей нетривиальной. Конечно в пользуясь только Mictosoft Visual Studio можно даже не подозревать о существовании этих файлов, так как интегрированная среда разработки достаточно удобно скрывает всю кухню, оставляя снаружи несколько диалоговых окон и кнопку Build. Но для сложных проектов использующих массу сторонних библиотек и кроссплатформенных проектов такой подход часто оказывается неприемлемым.

Кратко говоря make-файл представляет из себя описания последовательности действий необходимых для того чтобы достичь какой либо цели, например скомпилировать программу. На псевдокоде это может выглядеть примерно так:

Что нужно сделать?

Собрать программу hello_world.

Как ее делать?

Взять файлы hello_world.h и hello_world.cpp и запустить компилятор передав их в качестве параметров.

Что делать когда компилятор закончит работать?

Взять получившийся в результате работы компилятора объектный файлы hello_world.o и запустить линковщик передав ему этот файл.

Все.

Причем каждый подпроект может иметь свой файл сборки, а главный make-файл сможет пройти рекурсивно по подпроектам, выполнив его файл сборки, а потом собрать проект из этих компонентов.

Выглядит все просто, проблемы возникают дальше и проблем несколько:

  1. Разрешение зависимостей возникающих между частями проекта
  2. Синтаксическая сложность и неоднозначность классических make-файлов
  3. Привязка к конкретной утилите автоматической сборки и как следствие непереносимость на другие платформы

Для решения части этих проблем или всех сразу были созданы следующие инструменты: Automake (http://sourceware.org/automake/) , CMake (http://www.cmake.org/), SCons (http://www.scons.org/). Список далеко не полный.

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

Читать заметку полностью »

7th Январь 2010
20:52

Рубрика: Разработка,Сборка

Метки:


Работа с ветвями в SVN

1 комментарий

От основной ветки разработки можно отделить ветвь являющуюся ее копией на данный момент времени. Этим решаются следующие задачи:

  • Фиксация состояния разработки (например выпуск новой версии) к которому можно будет вернуться в любой момент.
  • Разработка независимо от основной ветви — актуально когда над проектом работают несколько разработчиков.

В этой заметке будут рассмотрены эти возможности, а также подводные камни работы с ветками и о том как их избежать.

Читать заметку полностью »

19th Декабрь 2009
21:29