В моем заголовке У меня есть объявление прототипа, похожее на это:
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);
В сгенерированном Doxygen HTML непросто выяснить, какой параметр какой. Конечно, здесь можно следовать тому же порядку, но если у него много параметров, это по-прежнему сбивает с толку.
Альтернативой может быть дублирование имен параметров и попытка их синхронизировать. Тем не менее, некоторые люди не t поощряют такой подход, говоря, что параметры заголовка должны начинаться с двойного подчеркивания, чтобы пользователь метода не мог использовать одно и то же имя (имена, начинающиеся с __, запрещены в C ++).
Как вы это делаете?
Конечно, если «имена, начинающиеся с __, запрещены в C ++», вам также не следует использовать их в прототипах :-) * a
Я вижу два способа сделать это.
Во-первых, вы можете гарантировать, что порядок параметров в ваших комментариях всегда соответствует порядку в вашем прототипе.
Или, во-вторых, вы также можете добавить настоящие имена в свои прототипы.
Лично я предпочитаю второй подход, так как мне нравится иметь возможность определять, какие параметры передаются, даже если функция не имеет комментариев к ним (или, что еще хуже, комментарии устарели). Это намного проще с таким прототипом, как:
void move(int xcoord, int ycoord);
, чем с:
void move(int, int);
В некоторых средах мы даже зашли так далеко, что процесс сборки гарантирует, что все прототипы функций имеют идентично названные параметры, как определение функции. .
* a) Эти идентификаторы не предназначены для использования в обычных программах. В разделе 17.6.3.3.2 cpp0x (но это ограничение существует уже довольно давно как в C, так и в C ++) говорится:
Определенные наборы имен и сигнатур функций всегда зарезервированы для реализации:
- Каждое имя, которое содержит двойное подчеркивание
__
или начинается с подчеркивания, за которым следует заглавная буква, зарезервировано для реализации для любого использования.- Каждое имя, начинающееся с подчеркивания, зарезервировано для реализации для использования в качестве имени в глобальном пространстве имен.
Другими словами, не используйте их в своих целях.
Ужасная идея не называть параметры в заголовке, если неясно, для чего этот параметр. Заголовок должен быть документацией для вашего кода, чтобы кто-то, пытающийся его использовать, мог избежать чтения реализации. Как вы обнаружили, бессмысленно документировать параметры по имени, а затем не сообщать пользователю, что есть что. Это не значит, что они должны совпадать, но в заголовке они должны быть значимыми для пользователей вашего кода. В реализации выберите наиболее подходящее для вас имя. Например. было бы вполне возможно иметь:
.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?"
Что такое объявление protype, это то, что вы сообщаете компилятору, что этот тип функции будет приходить с такими-то аргументами и с такими-то типами данных. Таким образом, компилятор создаст условия для этого типа аргументов.
следовательно, тип данных proto и количество аргументов должны соответствовать реальному определению и использованию во время выполнения.
В противном случае это приведет к ошибке времени выполнения.
C и C ++ в этом отношении одинаковы. Имена прототипов не обязательно должны совпадать… поэтому , почему они могут быть опущены.
Выберите имена для параметров; когда вы помещаете их в Doxygen, они становятся частью вашего API. Вы можете изменить их позже, но вы меняете API; вы также можете изменить их в реализации, но тогда они не будут точно соответствовать спецификации.
Не используйте двойное подчеркивание даже для «игнорируемых» идентификаторов. Компилятор может определять все, что начинается с двойного подчеркивания, что может означать что угодно, что может вызвать синтаксическую ошибку. Такие слова не просто запрещены для имен переменных в области видимости, они совершенно токсичны.
Они не обязательно должны совпадать, но я считаю имена параметров бесценной документацией. Я ненавижу, когда они отсутствуют. Мне гораздо больше нравится документация в коде, чем документация в комментариях.
А совет в конце этой ссылки действительно глуп. Имена параметров не представляют собой ничего особенного с точки зрения опасности быть переопределенными с помощью #define
. Имена функций и практически любые другие идентификаторы в вашем заголовке также находятся в опасности. Именно поэтому существует соглашение об использовании ALL_UPPERCASE для имен #define
.
Нет, сделайте так, чтобы имена совпадали в вашей реализации и в вашем заголовке, даже если компилятор будет в порядке, если они не совпадают. А если они не совпадают, исправьте их так, чтобы они совпадали. Они обеспечивают отличную документацию и будут сбивать с толку, если они не совпадают.
НЕПРАВИЛЬНЫЕ названия документации / параметров ВСЕГДА ХУЖЕ, чем НИКАКИХ названий документации / параметров. Я не говорю, что вам не нужна документация или имена параметров - я говорю, что вам лучше не отставать от них! Вот почему они платят нам большие $$$ :-D
Я всегда использую имена параметров как в заголовке, так и в реализации. Синхронизировать их несложно - когда я меняю параметры функции, я обычно:
* Добавить / удалить параметр (здесь нет проблем - вы должны синхронизировать его, даже если вы не использовали имена параметров)
* Измените порядок, чтобы он был более логичным (опять же, даже типы должны быть синхронизированы)
Преимущество наличия имен параметров как в прототипе, так и в реализации заключается в том, что это помогает пользователю - он может видеть имена в своем коде IDE завершение, ему не нужно переходить к определению (которое может быть недоступно), чтобы узнать имена параметров. Еще одна веская причина придерживаться этой практики - проблема с Doxygen.
Я также не вижу смысла использовать двойное подчеркивание в параметрах прототипа. Да, #defines - зло, но двойные подчеркивания зарезервированы для авторов компиляторов. Если вы не напишите стандартный заголовок для своего компилятора, вам следует его избегать.
Если файл заголовка принадлежит OEM-библиотеке, которая, как ожидается, будет использоваться многими сторонними поставщиками, любознательными разработчиками (такими как и те, которые принадлежат SO), наверняка изучат файлы заголовков в дополнение к предоставленной документации, учитывая тот факт, что в большинстве случаев документация либо очень плохая, либо значительно отстает от кода.
Таким образом, я бы сказал, что проблемы, упомянутые в отношении наименования параметров , могут вызвать затруднения во время разработки, но почти наверняка доставят удовольствие клиентам.