Когда использовать Заголовочные файлы, которые не объявляют класс, но имеют определения функций - PullRequest
6 голосов
/ 24 мая 2009

Я довольно новичок в C ++, и я видел множество кода, у которого есть определения методов в заголовочных файлах, и они не объявляют заголовочный файл как класс. Может кто-нибудь объяснить мне, почему и когда вы будете делать что-то подобное. Это плохая практика?

Заранее спасибо!

Ответы [ 5 ]

11 голосов
/ 24 мая 2009

Это плохая практика?

Не в общем. Есть много библиотек header only, что означает, что они поставляют только заголовочные файлы. Эту можно рассматривать как легкую альтернативу скомпилированным библиотекам.

Что еще более важно, однако, есть случай, когда вы не можете использовать отдельные предварительно скомпилированные модули компиляции: шаблоны должны быть специализированы для того же модуля компиляции, в котором они объявлены. Это может показаться загадочным, но имеет простое следствие:

Шаблоны функций (и классов) не могут быть определены внутри файлов cpp и использованы где-либо еще; вместо этого они имеют , который должен быть определен непосредственно в заголовочных файлах (с несколькими заметными исключениями).

Кроме того, классы в C ++ являются чисто дополнительными - хотя вы можете программировать объект, ориентированный на C ++, много хорошего кода не делает. Классы дополняют алгоритмы на C ++, а не наоборот.

4 голосов
/ 24 мая 2009

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

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

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

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

Еще больше, пространства имен помогают.

Иногда, однако, проще всего написать функцию, которая что-то делает. Это часто бывает, когда вы пишете функцию, которая работает только с примитивными типами (например, int). У int нет класса, поэтому, если вы хотите написать функцию printInt (), вы можете сделать ее автономной. Кроме того, если функция работает с объектами из нескольких классов, но на самом деле не принадлежит одному классу, а не другому, это может иметь смысл как отдельная функция. Это часто случается, когда вы пишете такие операторы, как define, less, чтобы сравнивать объекты двух разных классов. Или, если функция может быть написана в терминах открытых методов класса и не нуждается в непосредственном доступе к данным класса, некоторые люди предпочитают писать это как отдельную функцию.

Но, действительно, выбор за вами. Что бы ни было самым простым для решения вашей проблемы, лучше всего.

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

1 голос
/ 24 мая 2009

H-файл - это просто способ включения нескольких объявлений. Многие вещи в C ++ являются полезными объявлениями, включая классы, типы, константы, глобальные функции и т. Д.

C ++ имеет сильный объектно-ориентированный аспект. Большинство ОО-языков решают вопрос о том, где иметь дело с операциями, которые не зависят от состояния объекта и фактически не нуждаются в объекте.

В некоторых языках, таких как Java, языковые ограничения заставляют все быть в классе, поэтому все становится статической функцией-членом (например, классы с математическими утилитами или алгоритмами).

В C ++ для обеспечения совместимости с C вы можете объявлять автономные функции в стиле C или использовать стиль статических членов в стиле Java. Мое личное мнение таково, что по возможности лучше использовать стиль ОО и организовывать операции вокруг центральной концепции.

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

0 голосов
/ 24 мая 2009

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

Позволяет уточнить вещи.

определения методов в заголовочных файлах

Это означает что-то вроде этого: файл "А.ч":

class A {
void method(){/*blah blah*/} //definition of a method
};

Это то, что вы имели в виду?

Позже вы говорите "объявить файл заголовка". Нет механизма для декларирования файла в C ++. Файл может быть ВКЛЮЧЕН с помощью #include "filename.h". Если вы сделаете это, содержимое файла заголовка будет скопировано и вставлено туда, где есть указанная выше строка, прежде чем что-либо будет скомпилировано.

Таким образом, вы имеете в виду, что все определения находятся в определении класса (не в любом месте A.h FILE, а конкретно в классе A, который ограничен 'class A {' и '};'). Следствием наличия определения метода в определении класса является то, что метод будет «встроенным» (это ключевое слово C ++), что означает, что тело метода будет вставлено при каждом обращении к нему. Это:

  • хорошо, потому что механизм вызова функций больше не замедляет выполнение
  • плохо, если функция длиннее короткого оператора, потому что размер исполняемого кода сильно увеличивается

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

0 голосов
/ 24 мая 2009

В C ++ функции не обязательно должны быть членами классов.

...