Есть хороший способ избежать дублирования прототипов методов в C ++? - PullRequest
3 голосов
/ 30 октября 2009

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

Кто-нибудь порекомендует способ избежать этого? Или я в основном собираюсь сбить с толку опытных программистов на C ++ тем, что не веду себя как обычно?

См. Также Вопрос 538255 Код C ++ в заголовочных файлах , где кто-то говорит, что все должно идти в заголовке.

Ответы [ 5 ]

9 голосов
/ 30 октября 2009

Есть альтернатива, но лекарство хуже, чем болезнь & mdash; определить все тела функций в заголовке или даже в строке в классе, как C #. Недостатки в том, что это значительно увеличит время компиляции и будет раздражать опытных программистов на C ++. Это также может привести вас к некоторым неприятным ситуациям круговой зависимости, которые, хотя и разрешимы, но и мешают.

Лично я просто установил в своей IDE вертикальное разделение и поместил заголовочный файл справа и исходный файл слева.

6 голосов
/ 30 октября 2009

Я предполагаю, что вы говорите о функции-члене объявлений в заголовочном файле и определениях в исходных файлах?

Если вы привыкли к Java / Python / и т.д. Модель может показаться излишней. Фактически, если бы вы были так склонны, вы могли бы определить все встроенные функции в определении класса (в файле заголовка). Но вы определенно будете нарушать соглашение и платить цену дополнительного времени компоновки и компиляции каждый раз, когда вносите незначительные изменения в реализацию.

C ++, Ada и другие языки, изначально разработанные для крупномасштабных систем, держали определения скрытыми по какой-то причине - нет веской причины, по которой пользователи класса должны интересоваться его реализацией, а также причин, по которым они должны это делать. неоднократно платить, чтобы скомпилировать его. Меньше проблем в наши дни с более быстрыми системами, но все еще актуальными для действительно больших систем. Кроме того, TDD, stubbing и другие стратегии тестирования облегчаются изоляцией и более быстрой компиляцией.

4 голосов
/ 30 октября 2009

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

3 голосов
/ 30 октября 2009

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

0 голосов
/ 30 октября 2009

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

е

InterfaceClass* InterfaceClass::Create()
{
     return new ImplementationClass;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...