Что лучше всего подходит для С++ Public API?

Какова наилучшая практика для открытого API С++?

Я работаю над проектом С++, который имеет несколько пространств имен, каждый из которых имеет несколько объектов. Некоторые объекты имеют одинаковые имена, но находятся в разных пространствах имен. В настоящее время каждый объект имеет свой собственный .cpp файл и .h файл. Я не уверен, как это сказать... Было бы целесообразным создать второй файл .h, чтобы открыть только публичный API? Должны ли они быть .h файлом для пространства имен или для объекта или какой-либо другой области? Что может быть лучшей практикой для создания публичных API для библиотек С++?

Спасибо за любую помощь, Chenz

Ответ 1

Иногда бывает удобно иметь один класс в каждой паре файлов .cpp и .h и иметь иерархию пространства имен в качестве иерархии каталогов.
Например, если у вас есть этот класс:

namespace stuff {
  namespace important {
    class SecretPassword 
    {
       ...
    };
  }
}

то он будет в двух файлах:

/stuff/important/SecretPassword.cpp
/stuff/important/SecretPassword.h

другой возможный макет может быть:

/src/stuff/important/SecretPassword.cpp
/include/stuff/important/SecretPassword.h

Ответ 2

G'day,

Одно из предложений - взглянуть на идиому С++ для Handle-Body, которую иногда называют Cheshire Cat. Здесь оригинальная статья Джеймса Коплиена, содержащая идиому.

Это хорошо известный метод развязки открытого API из реализаций.

НТН

Ответ 3

Я бы сказал, что это наилучшим образом определено вами, а тип "библиотеки" - это.

Является ли ваш API одним "действием"? или обрабатывает только один абстрактный "Тип данных"? примерами для этого были бы zlib и libpng. Оба имеют только один заголовок, который дает все, что необходимо для выполнения того, для чего предназначены библиотеки.

Если ваша библиотека представляет собой коллекцию несвязанных (или даже связанных) классов, которые выполняют или не выполняют одну и ту же цель, то предоставляйте каждому подмножеству свой собственный заголовок. Основным примером этого будет повышение.

Ответ 4

Вот что я использовал:

"Некоторые объекты имеют одинаковые имена, но находятся в разных пространствах имен"

Вот почему существуют пространства имен.

"Было бы целесообразным создать второй .h файл, чтобы открыть только публичный API?"

Вы всегда должны публиковать только открытый API. Но что значит публиковать открытый API? Если бы тогда были только заголовки, поскольку публичный API полагался на частный API, частный API был бы включен публичным API в любом случае. Чтобы публиковать общедоступные API-метки публичных функций/классов с макросом (который в случае Windows экспортирует публичные функции в таблицу символов и, вероятно, вскоре будет принят системами Unix). Поэтому вы должны определить макрос, например MYLIB_API или MYLIB_DECLSPEC, просто проверьте некоторые существующие библиотеки и документацию MS declspec. Достаточно, обычно непубличный API будет храниться в подкаталогах, чтобы он не посещал пользователя библиотеки.

"Должны ли они быть файлом .h для пространства имен или для объекта или какой-либо другой области?"

Я предпочитаю Java-стиль, один общедоступный класс для каждого заголовка. Я обнаружил, что листы, написанные таким образом, намного чище и читабельны, чем те, которые смешивают имена файлов и структуры. Но бывают случаи, когда я торможу это правило, особенно когда дело касается шаблонов. В таких случаях я даю сообщение #warning, чтобы не включать заголовок напрямую и тщательно объяснять в комментариях, что происходит.

Ответ 5

Великий ответ LiraNuna.

Предоставляете ли вы API для приложения или библиотеки?

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

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

Ответ 6

Я согласен с тем, что сказал doc - один класс в файле. 99,9% времени!

Также рассмотрите, какие имена файлов использовать. Как правило, плохая идея иметь несколько заголовков одного и того же имени в разных каталогах, хотя классы, которые они содержат, вполне могут находиться в разных пространствах имен.

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

Мы используем соглашение об именах Namespace-Class.h для явного определения классов в файлах.