Имена параметров прототипа - PullRequest
7 голосов
/ 22 августа 2010

В моем заголовке у меня есть объявление прототипа, подобное этому:

void move(int, int);

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

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

/**
 * Moves the entity to the specified point.
 * @param x The x coordinate of the new position.
 * @param y The y coordinate of the new position.
 */
void move(int, int);

В сгенерированном HTML-коде Doxygen нелегко определить, какой параметркоторый.Конечно, здесь можно следовать тому же порядку, но если у него много параметров, это по-прежнему сбивает с толку.

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

Как ты это делаешь?

Ответы [ 8 ]

10 голосов
/ 22 августа 2010

Страшная идея не называть параметры в заголовке, если неясно, для чего этот параметр.Заголовок должен быть документацией для вашего кода, чтобы кто-то, пытающийся его использовать, мог избежать чтения реализации.Как вы обнаружили, бессмысленно документировать параметры по имени, а затем не указывать пользователю, какой именно.Это не значит, что они должны совпадать, но в заголовке они должны быть значимыми для пользователей вашего кода.В реализации выберите имя, которое лучше всего подходит для вас.Например, было бы вполне возможно иметь:

.h:

void move(int x, int y);

.cpp:

void move(int deltaX, int deltaY)
{
   ...

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

void SetNumPotatoes(int);
void EnableLights(bool);
void InitFoo(Foo&);

// but then...
T& GetItem(int);  // probably obvious enough, but does typing 'index' kill you?
void DoSomething(bool, float, int);  // someone using this will say, "WTF?"
5 голосов
/ 22 августа 2010

Конечно, если «имена, начинающиеся с __, запрещены в C ++», вы также не должны использовать их в прототипах :-) * a

Я вижу два способа сделать это.

Во-первых, вы можете убедиться, что порядок параметров в ваших комментариях всегда соответствует порядку в вашем прототипе.

Или, во-вторых, вы могли бы также ввести настоящие имена в свои прототипы.

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

void move(int xcoord, int ycoord);

, чем с:

void move(int, int);

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


* a) Эти идентификаторы фактически не предназначены для использования в обычных программах. Раздел 17.6.3.3.2 cpp0x (но это ограничение существует довольно давно как в C, так и в C ++) сообщает:

Определенные наборы имен и сигнатур функций всегда зарезервированы для реализации:

  • Каждое имя, которое содержит двойное подчеркивание __ или начинается с подчеркивания, за которым следует заглавная буква, резервируется для реализации для любого использования.
  • Каждое имя, начинающееся с подчеркивания, зарезервировано для реализации для использования в качестве имени в глобальном пространстве имен.

Другими словами, не используйте их в своих целях.

3 голосов
/ 22 августа 2010

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

И совет в конце этой ссылки действительно глупый. Имена параметров не являются чем-то особенным, поскольку они могут быть переопределены с помощью #define. Имена функций и практически любой другой идентификатор в вашем заголовке также находятся в опасности. Вот почему существует соглашение об использовании имен ALL_UPPERCASE для ваших #define имен.

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

2 голосов
/ 22 августа 2010

НЕПРАВИЛЬНЫЕ названия документации / параметров ВСЕГДА БОЛЬШЕ, чем НИКАКИХ документов / имен параметров. Я не говорю, что вам не нужны документация или имена параметров - я говорю, что вам лучше не отставать от них! Вот почему они платят нам большие $$$: -D

1 голос
/ 22 августа 2010

Я всегда использую имена параметров как в заголовке, так и в реализации. Не сложно синхронизировать их - когда я меняю параметры функции, я обычно:
* Добавить / удалить параметр (здесь нет проблем - его нужно синхронизировать, даже если вы не использовали имена параметров).
* Измените порядок, чтобы он был более логичным (опять же, даже типы должны синхронизироваться)

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

Я также не вижу смысла в использовании двойных подчеркиваний в параметрах прототипа. Да, #defines - зло, но двойные подчеркивания зарезервированы для авторов компиляторов. Если вы не пишете стандартный заголовок для вашего компилятора, вам следует избегать его.

0 голосов
/ 23 августа 2010

Что такое объявление прототипа, так это то, что вы информируете компилятор о том, что функция такого типа будет идти с этими аргументами и с этими типами данных. Таким образом, компилятор сделает упорядочивание для аргументов такого типа.

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

В противном случае это приведет к ошибке времени выполнения.

0 голосов
/ 23 августа 2010

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

Таким образом, я бы сказал, что упомянутые проблемы с именованием параметров могут причинять боль времени разработки, но почти наверняка вызывают восторг клиента.

0 голосов
/ 22 августа 2010

C и C ++ одинаковы в этом отношении.Имена прототипов не должны совпадать… вот почему , поэтому они могут быть опущены.

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

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

...