Неужели никогда невозможно написать библиотеку только для заголовков?

StackOverflow https://stackoverflow.com/questions/3753757

  •  04-10-2019
  •  | 
  •  

Вопрос

Существует ли когда-нибудь такая схема зависимостей, что невозможно сохранить все только в заголовочных файлах?Что, если бы мы применили правило только для одного класса для каждого заголовка?

Для целей этого вопроса давайте проигнорируем статические вещи :)

Это было полезно?

Решение

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

Другие советы

Можно, я бы сказал, в экспресс-состоянии не используя ряд языковых функций: как вы заметили, несколько использований static ключевое слово.

Это может потребовать несколько трюков, но их можно рассмотреть.

  1. Вам нужно будет сохранить различие заголовка / источника, когда вам нужно разбить цикл зависимости, даже если два файла будут заголовками файлами на практике.
  2. Свободные функции (не шаблон) должны быть объявлены встроенным, компилятор не может их встроить, но если они объявлены, поэтому он не пожаловался, что они были переопределены, когда клиент чистит свою библиотеку / исполняемый файл.
  3. Всемирно общие данные (глобальные переменные и статические атрибуты класса) должны быть эмулированы с использованием локального статического атрибута в функциях / классных методах. На практике это имеет значение мало, насколько вызывает абонент (просто добавляет ()). Обратите внимание, что в C ++ 0x это становится благоприятным способом, потому что он гарантированно будет безопасен в потоке во время того, чтобы все еще защищавшись от фиаско по порядку инициализации, до тех пор, пока ... это не безрезультатно;)

Уважая эти 3 очка, я полагаю, что вы сможете написать полностью непредушенную библиотеку только заголовок (кто-нибудь видит что-то еще, что я пропустил?)

Ряд библиотек Boost использовали подобные трюки, чтобы быть заголовками, даже если их код не был полностью шаблон. Например Asio делает очень сознательно и предлагает альтернативу, используя флаги (см. Отпустите ноты для ASIO 1.4.6):

  • клиенты, которым нужна только пара функций, не нужно беспокоиться о строительстве / связи, они просто захватывают то, что им нужно
  • Клиенты, которые полагаются на него немного больше или хотите сократить время компиляции, предлагаются возможность создавать собственную библиотеку ASIO (со своими собственными наборами флагов), а затем включают в себя «легкие» заголовки

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

Примечание: Мне интересно, static Функции могут быть установлены, я предпочитаю использовать анонимные пространства имен, поэтому никогда не смотрел в него ...

Один класс на правило заголовка бессмыслен. Если это не работает:

#include <header1>
#include <header2>

Тогда некоторая вариация этого будет:

#include <header1a>
#include <header2>
#include <header1b>

Это может привести к менее чем одному классу на заголовок, но вы всегда можете использовать (void *) и отливки и встроенные функции (в этом случае «встроенный», вероятно, будет должным образом игнорироваться компилятором). Таким образом, вопрос, кажется мне, может быть уменьшен до:

class A
{
// ...
void *pimpl;
}

Возможно ли, что частная реализация, Pimpl, зависит от декларации a? Если это так, то pimpl.cpp (как заголовок) должен оба предшествовать, и следуют AH, но, поскольку вы всегда можете, еще раз, используете (void *) и отливки и встроенные функции в предыдущих заголовках, это можно сделать.

Конечно, я мог быть неправ. В любом случае: ICK.

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

Вдом, если у вас есть круговые зависимости между классами, вам может потребоваться прибегнуть к абстрактному интерфейсу - бетонную парадигму реализации или использование шаблонов (с использованием шаблонов позволяет пересылать свойства / методы параметров шаблонов, которые решаются позже во время реализации ).

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top