The K Desktop Environment

Next Previous Table of Contents

15. Советы по программированию

В конце этой книги я хочу обратить внимание на некоторые моменты, о которых надо помнить при разработке. Это в основном советы по программированию на C++, которые относятся к KDE и особенно Qt, и взяты в центре разработчиков KDE, который можно найти в Internet по адресу http://www.kde.org.

Имена файлов

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

Имена классов

Имена классов в приложении KDE должны:

  • начинаться с префикса K, затем следует имя, описывающее назначение класса (по вашему выбору). Например, KMyWidget для специального элемента приложения,
  • иметь членов, имена которых начинаются только со строчной буквы, а следующие слова в них начинаются с заглавной, например, myWidgetPointer(),
  • называть методы, которые возвращают значения private-атрибутов, без использования префикса get. Используйте содержательное имя члена класса. Например, b_myboolean - private член. Метод, возвращающий текущее значение, может называться myBoolean().

Обращение к файлам в коде

Следует избегать жесткого задания путей, используя стандарт файловой системы KDE. Вы должны только определить путь к вашему приложению, это можно сделать с помощью соответствующего макроса в файле Makefile.am, как это было описано выше. В коде используйте методы KApplication для получения действительных путей.

Документация классов

Еще один пункт, который уже упоминался, - документация классов. Вы должны придерживаться правил форматирования KDoc, поскольку их используют все разработчики KDE для документирования классов. Добавьте хотя бы одну строку комментариев к каждому члену класса себе для напоминания его предназначения и другим для повторного использования кода. Повторное использование кода с GPL имеет больше смысла, когда вы знаете, где найти уже существующее решение по документированному классу. Qt-библиотека - хороший пример хорошо документированного интерфейса, хотя он не использует KDoc.

Используйте new для создания элементов

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

Отладка

Когда дело доходит до отладки, используйте макрос KDebug. Есть похожие макросы Qt, но он обеспечивает доступ с свойствам через клавиши STRG+ALT+F12. См. KDE Library Reference Guide для более подробной информации о фильтрации событий этим макросом. Вы также можете использовать assert(), но поддерживайте соответствие с кодом для отладки.

Объявления const

Используйте объявление const для функций-членов, которые не меняют значений private-членов. Это можно использовать для всех методов, возвращающих значения этих членов. Это позволяет избежать случайного изменения значения и отловить логические ошибки на этапе компиляции. Что касается инициализации членов с декларацией const, вы должны это делать одновременно с использованием static в определении, и инициализировать значение вне конструктора:

class foo {
        static const int value;
};

const foo::value = 10;

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

Виртуальные методы

Как объяснялось в разделе Взаимодействие с пользователем, вы должны учитывать права доступа и декларацию virtual при перекрывании виртуальных методов. По крайней мере, вы не должны уменьшать доступ к виртуальному методу от protected до private.

Предварительные объявления

Заголовки классов должны быть включены там, где вы обращаетесь к объекту или экземпляру класса в вашем коде. Это значит, что если ваш класс использует член другого класса, замените директиву #include предварительным описанием класса, например, вместо:

#include <qpushbutton.h>

class KMyWidget:public QWidget
{

private:
  QPushButton* ok_button;
};

предпочтительнее только объявить класс QPushButton в файле заголовка:

class QPushButton;

class KMyWidget:public QWidget
{

private:
  QPushButton* ok_button;
};

и поместить директиву include в соответствующий файл-исходник, где, например, экземпляр ok_button используется любым методом класса QPushButton. Это сохранит время компилятора, особенно если вы используете экземпляры классов, которые вы разрабатываете. Компилятор должен перекомпилировать все исходники, включающие заголовок, если вы делаете любое изменение в интерфейсе класса, поэтому простое добавление метода, возвращающего целое значение внутреннего объекта, может привести к перекомпиляции всех исходников, включающих файл заголовка данного класса.

Сообщения о неиспользуемых параметрах и значения по умолчанию

Также вы должны удалить формальные параметры методов, которые не являются необходимыми. Это позволит избежать предупреждения unused parameter от вашего компилятора, когда он увидит формальный параметр, который не используется в реализации. Обычно вы посылаете несколько аргументов по умолчанию в некоторые методы. Их значения необходимо устанавливать в объявлении члена класса, а не в его реализации.

Использование config.h

Проекты KDevelop, как и любые другие проекты, использующие autoconf для создания скриптов configure, создают файл config.h после выполнения скрипта configure на пользовательской машине. В нем приводятся значения, найденные configure, которые могут быть использованы в исходниках. Директива для включения файла config.h следующая:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Один из наиболее часто используемых входов config.h, вероятно, определение типа bool для компиляторов, которые не совместимы с проектами последних версий ANSI C++.

Используйте 0 вместо NULL

Предпочитайте использовать 0 непосредственно вместо NULL для установки значений, как это делают библиотеки KDE и Qt. Это повышает переносимость ваших приложений для компиляторов, которые имеют проблемы с использованием NULL.

Временные данные

Вы должны определять временные экземпляры всегда перед их использованием. Это лучший путь, чем прямое использование. Пример:

// Не следует
for( int i=0; i<n; i++){
  //что-то делаем
  };

// Следует
int i;

for(i=0; i<n; i++){
  //что-то делаем
  };

Это также касается вызовов функций:

// Не следует
setColor( &(QColor(black)) );

// Следует
QColor color(black);
setColor( &color );

Next Previous Table of Contents