Skip to content

Coding style

Alexandr Akulich edited this page Mar 23, 2016 · 4 revisions

Table of Contents

Именование файлов C++

  • Каждый класс в двух отдельных файлах, базовое имя которых совпадает с названием класса:
  • Реализация в .cpp.
  • Объявления в .hpp. (Расширение .h относится к языку Cи. Объявление структуры класса не является валидным Си-кодом.)

Имена собственных типов, переменных, методов и т.д.

  • Все поля должны начинаться с m_. (member)
  • Имена функций и переменных должны быть в camelCase.

Отступы, форматирование

  • Табов в исходном тексте программы быть не должно. Совсем.
  • Вместо табуляции - 4 пробела. (Оба правила по-умолчанию автоматически выполняются в среде Qt Creator)
  • Должны быть пробелы между ключевыми словами и параметрами.
  • Обязательны пробелы между мат. операциями. (supposedNewPosition = position + supposedTotalSpeed * dT + totalAcceleration * dT * dT / 2;)
  • Открывающаяся фигурная скобка, начинающая функцию, либо определение класса, пишется с новой строчки.
  • Каждая новая открывающаяся фигурная скобка пишется на той же строчке, что и относящийся к ней оператор.
  • После открывающейся фигурной скобки всегда следует перенос строки, либо оператор else (else if).

Пробелы, переносы строк

  • Для разделения можно использовать только одну пустую линию.
  • Допускается перенос параметров на следующую строку.
  • После ключевого слова и перед фигурной скобкой (если она не является первым символом в строке) всегда ставится ровно один пробел.
  • Для указателей и ссылок: всегда ставится один пробел между типом и ‘*’ или ‘&’, но никогда не ставится пробел между ‘*’ или ‘&’ и названием переменной.
Пример:
void CTelegramDispatcher::ensureSignedConnection(CTelegramConnection *connection)
{
    if (connection->status() == CTelegramConnection::ConnectionStatusDisconnected) {
        connection->connectToDc();
    } else {
        // If need an exported auth to sign in
        if (connection->authState() == CTelegramConnection::AuthStateHaveAKey) { 
            quint32 dc = connection->dcInfo().id;

            if (m_exportedAuthentications.contains(dc)) {
                connection->authImportAuthorization(m_exportedAuthentications.value(dc).first,
                                                  m_exportedAuthentications.value(dc).second);
            } else {
                if (activeConnection()->authState() == CTelegramConnection::AuthStateSignedIn) {
                    activeConnection()->authExportAuthorization(dc);
                }
            }
        }
        // Else - nothing to do.
    }
}

Определение класса

Порядок секций:

  1. public
  2. public slots
  3. signals
  4. protected slots
  5. protected
  6. private slots
  7. private
Остальное:
  • Пустые секции нужно пропускать.
  • После каждой секции должна быть пустая строка.
  • Поля всегда перечисляются после функций.
Пример:
class CBase
{
public:
    bool isValid() const { return m_id != 0; }

    virtual CScriptAdaptor *scriptAdaptor() const = 0;
    virtual QStringList files() const;

public slots:
    void setId(quint32 newId);
    void setTitle(const QString &newTitle);

signals:
    void idChanged(quint32 newId);
    void titleChanged(QString newTitle);

protected:
    void copyHelper(const CBase *sourceBase);
    void copyStyle(const CBase *sourceBase);

private:
    quint32 m_id;
    QString m_title;

};

Другие общие правила

  • Всё, что может быть приватным (защищённым), должно быть приватным (защищённым).
  • Всё, что может быть const, должно быть const.
  • Использовать префиксную инкрементацию.
  • В заголовочных файлах следует подключать минимум заголовочных файлов — вместо этого следует использовать предварительное объявление.

Не допускается

  • Не допускается использование препроцессора для ввода переменных. Вместо этого следует создавать const static переменные нужного типа с нужным значением, либо использовать enum.