С++ - Есть ли преимущества использования #include <ClassName> вместо #include <classname.h>?

Я знаю, что стандартные библиотеки используют с .h для старых библиотек C и включает без .h для современных библиотек. Но какова лучшая практика для отдельных классов?

Где я работаю, у нас всегда была папка include с двумя файлами в классе: classname.h и ClassName. ClassName включает classname.h и classname.h включает в себя заголовок реального класса. Чтобы включить класс, используйте

#include <ClassName>

То, как Qt это делает, и я уверен, что Qt - причина, по которой они начали делать это в моей компании. Но есть ли какие-либо выгоды от этого?

Недостатки очевидны, я думаю:

  • Еще один файл для создания нового класса (мы делаем это с bash script, но все же)
  • Еще один файл для каждого класса для управления
  • При переименовании файла/класса с помощью среды IDE вам обычно нужно вручную адаптировать файл ClassName (даже Qt Creator не может этого сделать)
  • Я никогда не видел этот стиль нигде, кроме библиотеки std и Qt

Используете ли вы этот стиль? Если да, то почему? Каковы аргументы для этого? Есть ли больше аргументов против этого?

Ответ 1

Сначала, я собираюсь составить термин и называть его "Class-Specific Include File" или "CSIF" . Эти файлы не заканчиваются на .h, хотя они используются как заголовок, поэтому часть "include file". Поскольку я буду продолжать ссылаться на это, я мог бы также дать ему аббревиатуру.

Как это реализовано в Qt

Qt имеет "заголовочный" файл без расширения для каждого определенного Qt class или struct, известного как CSIF для этого ответа. CSIF идут прямо в путь \include с обычными файлами заголовков, но все они делают то же самое, если вы открываете один. Начнем с включения файлов QtWidgets, в частности, связанных с QStyleOption:

\include
    ...
    QStyleOption
    qstyleoption.h
    QStyleOptionButton
    QStyleOptionComboBox
    ...

Если вы откроете один из этих QStyleOption связанных CSIF, все они содержат одну строку кода:

#include "qstyleoption.h"

И в qstyleoption.h:

#include "../../src/widgets/styles/qstyleoption.h"

Все, что делает CSIF, это #include правильный заголовок из исходного дерева для класса, в котором он назван.. Он создает уровень абстракции между фактическим определением класса и #include, чтобы использовать его. В результате этот код:

//In some .cpp file somewhere
#include <QStyleOptionButton>
#include <QStyleOptionComboBox>

содержит тот же заголовочный файл (конечно, защищен охранниками), но разработчик, использующий Qt, не должен это знать. Все разработчики заботятся о том, что он/она использует класс, и он/она хочет быть уверенным, что класс доступен. Я не знаю, была ли это оригинальная логика, но что он имеет.

Ответы на ваши конкретные вопросы

1. Вы используете этот стиль? Если да, то почему?
Да, но только потому, что проект, над которым я работаю, эмулирует стиль библиотеки Qt, так что разработчики Qt могут удобно использовать его вместе с Qt. В противном случае, [вставьте обильное ругательство].

2. Каковы аргументы для этого?
Единственный хороший аргумент, который я знаю для него, - это выше, в том, как Qt использует его для абстрактных классов и местоположения их определений. Как пользователь Qt, гарантируя, что у меня есть правильные файлы заголовков, это легкий ветерок. Если я использую класс QFoo, я включаю: <QFoo>. Простой.

3. Есть ли еще аргументы против этого?
Есть много аргументов против этого, как вы отметили в своем вопросе.

  • Это делает рефакторинг во много раз сложнее.
  • Это действительно полезно, если вы разрабатываете библиотеку.
  • Стоит только ваше время, если ваша библиотека имеет гарантию стабильности API и достаточно зрелая, потому что она делает рефакторинг во много раз сложнее.
  • Это означает, что каждый класс, который экспортирует ваша библиотека, должен иметь CSIF, а отсутствующий - легко сделать.

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

Что касается того, как ваше рабочее место использует его... Я пожал плечами. Кто-то скопировал стиль Qt, не понимая почему, возможно?