Pull to refresh

Qt Coding Style

Reading time5 min
Views42K
Qt Coding Style по версии Qt
Привет, хабражители!

Сейчас какой-то спец с многолетним опытом работы с Qt подумал: «Что за фигня? Хабр — для вещей покруче!». Но ведь даже спецам с многолетним опытом иногда надо читать вот такие статьи про простые вещи, ведь это — важно. Код — это одна из самых важных составляющих программирования. А наша задача — держать его в чистоте. Эта статья посвящена всем Qt программистам которые стремятся к идеалу.

Конечно есть статья на Qt Project — Qt Coding Style. Только вот там материала ценного меньше…


Постулат №1. Выравнивание


В Qt принято использовать отступы по 4 пробела. Но именно 4, и именно пробела. Использовать \t или другую ширину пробелов считается ужасно плохим тоном и жестоко карается.

Постулат №2. Объявление переменных


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

  • Объявлять каждую переменную на отдельной строчке
  • Избегать коротких или немногословных названий (например «a», «rbarr», «nughdeget»)
  • Дождитесь, пока переменная будет нужна, и только тогда объявляйте ее
  • Функции и переменные должны быть в camelCase
  • Избегайте аббревиатур и всяческих сокращений
  • Классы всегда должны начинаться с заглавной буквы
  • Публичные классы должны начинаться с буквы ‘Q’ (QRgb), затем заглавная буква
  • Публичные функции должны начинаться с буквы ‘q’ (qRgb)
  • Аббревиатуры должны быть в PascalCase (например QXmlStreamReader вместо QXMLStreamReader)

// Неправильно
int a, b;
char *c, *d;
     
// Правильно
int height;
int width;
char *nameOfThis;
char *nameOfThat;

// Неправильно
short Cntr;
char ITEM_DELIM = '\t';
     
// Правильно
short counter;
char itemDelimiter = '\t';


Постулат №3. Пробелы


Пробелы — очень важный элемент форматирования исходного кода. Он отыгрывает очень большую роль в читабельности кода.

  • Используйте пробелы для группировки отдельных сегментов кода
  • Для разделения можно использовать только одну пустую линию
  • Всегда использовать только один, и только один пробел после ключевого слова и фигурной скобки
  • Для указателей и ссылок, всегда используйте один пробел между типом и ‘*’ или ‘&’, но никогда не ставьте пробел между ‘*’ или ‘&’ и названием переменной
  • Окружайте бинарные операторы пробелами
  • Никаких пробелов после приведения типов
  • Старайтесь избегать С-подобных приведений

// Неправильно
if (foo){
}
     
// Правильно
if (foo) {
}

char *x;
const QString &myString;
const char * const y = "hello";

MyClass *obj = new MyClass(this);
bool ok;
obj.report(1, &ok);

// Неправильно
char* blockOfMemory = (char* ) malloc(data.size());
QTextStrem newOne(..);
newOne<<"Hello"<<","<<" "<<"world";
     
// Правильно
char *blockOfMemory = reinterpret_cast<char *>(malloc(data.size()));
QTextStrem newOne(..);
newOne<< "Hello" << "," << " " << "world";


Постулат №4. Скобки


Скобки — это вообще отдельная тема. Они, как и пробелы, отыгрывают львиную долю во внешнем виде и читабельности кода

  • В качестве основного правила, левая фигурная скобка находится на той же строчке, что и оператор:
  • Исключение: Реализация функций и объявления классов всегда, абсолютно всегда располагают левую скобку на новой строчке:
  • Используйте фигурные скобки когда тело условия содержит более одной линии, и если однострочный оператор — что-то комплексное
  • Исключение 1: Также используйте скобки если родительский оператор занимает несколько линий или оберток
  • Исключение 2: Также используйте скобки в if-else блоках где if-код или else-код занимает несколько линий
  • Используйте фигурные скобки когда тело оператора — пустое

static void foo(int g)
{
    qDebug("foo: %i", g);
}

class Moo
{
public:
    Moo();
    Moo(int a, int b);

public slots:
    int getResult();

protected slots:
    void processNumbers();

private:
    int mineA;
    int mineB;
    int mineResult;
};

// Неправильно
if (address.isEmpty()) {
    return false;
}
for (int i = 0; i < 10; ++i) {
    qDebug("%i", i);
}
       
// Правильно
if (address.isEmpty())
    return false;
       
for (int i = 0; i < 10; ++i)
    qDebug("%i", i);

// Неправильно
while (a);
if (expression)  else
    // do something

// Правильно
while (a) {}
if (expression) {
} else {
    // do something
}


// Неправильно
if (codec)
{
    // do something
}
     
// Правильно
if (codec) {
    // do something
}

// Неправильно
if (address.isEmpty())
    return false;
else {
    qDebug("%s", qPrintable(address));
    ++it;
}

// Правильно
if (address.isEmpty()) {
    return false;
} else {
    qDebug("%s", qPrintable(address));
    ++it;
}

// Неправильно
if (a)
    if (b)
        ...
    else
        ...

// Правильно
if (a) {
    if (b)
        ...
    else
        ...
}

// Неправильно
if (address.isEmpty() || !isValid()
    || !codec) 
    return false;

// Правильно
if (address.isEmpty() || !isValid()
    || !codec) {
    return false;
}


Постулат №5. Круглые скобки


Используйте круглые скобки чтобы группировать выражения:
// Неправильно
if (a && b || c)
if (a + b & c)

// Правильно
if ((a && b) || c)
if ((a + b) & c)


Постулат №6. Условия множественного выбора switch


Безусловно, эти условия причина многих дискуссий со стороны разработчиков и создателей Coding Guidelines — там может быть очень много различных вариантов. Однако Qt предлагает именно такой вариант:

  • Операторы case должны находиться в той же колонке, что и оператор switch
  • Каждый случай должен заканчиваться оператором break (или return) или комментарием, чтобы показать чтоe далее следует другой случай


switch (myEnum) {
case Value1:
    doSomething();
    break;
case Value2:
case Value3:
    doSomethingElse();
    // fall through
default:
    defaultHandling();
    break;
}


Постулат №7. Разрыв строк


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

  • Старайтесь чтобы строки были не длиннее 100 символов; обрывайте их, если это необходимо
  • Коммы располагаются в конце оборванной строки; операторы следует переносить в начале новой строки. Оператор в конце строки очень просто не увидеть если ваш редактор слишком узкий

// Неправильно
if (longExpression +
    otherLongExpression +
    otherOtherLongExpression) {
}

QMessageBox::information(d->someObjectWithLongName, tr("A long title for mesage"), tr("A very very very very very very long body", QMessageBox::Ok, QMessageBox::Cancel);

// Правильно
if (longExpression
    + otherLongExpression
    + otherOtherLongExpression) {
}

QMessageBox::information(d->someObjectWithLongName,
                                                  tr("A long title for mesage"),
                                                  tr("A very very very very very very long body", 
                                                  QMessageBox::Ok, QMessageBox::Cancel);

UPD: последний участок кода отображается неверное — там все строчки должны быть на одном уровне

Постулат №8. Наследование и ключевое слово `virtual`


В этом постулате все предельно просто — главное не писать `virtual` перед названием переопределяемого метода в .h файле.
// Неправильно
class MyWidget : public QWidget
{
...
protected:
    virtual void keyPressEvent(QKeyEvent *);

// Правильно
class MyWidget : public QWidget
{
...
protected:
    void keyPressEvent(QKeyEvent *);


Постулат №9. Общее исключение


Этот постулат гласит нам, что нет ничего плохого если вы нарушите какое-то правило, но только в том случае, если оно делает ваш код уродливым. Это хороший пример того, что у всех правил есть исключения, и того, что правила созданы чтобы их нарушать.

К сожалению, я не смог найти примера, когда Qt Coding Guidelines делают код — уродливым.

Завершение


Боюсь что это конец моей статьи про стиль написания кода в Qt. Еще раз напомню что только он котируется для контрибьютинга в Qt, так что если вы собираетесь внести свою лепту в развитие проекта, вам так или иначе придется использовать эти постулаты, но не забывайте — правила можно нарушать:).

Для меня — Qt Coding Style просто идеальный стиль для написания кода. Я считаю его чистым, удобным, приятным. За все время его использования у меня не возникло никаких проблем с читабельностью кода. Буду ли я его рекомендовать? Конечно, да! Тем более, я считаю что именно его и надо пропагандировать всем новичкам на платформе Qt.

Спасибо за внимание.
Tags:
Hubs:
+35
Comments109

Articles

Change theme settings