Учитывая, что это стилистический вопрос, он вызовет некоторые субъективные ответы, в том числе и мой.: -)
Существуют процедурные языки, которые требуют, чтобы параметры функции были определены как входные или выходные.В C ++ это в значительной степени не нужно.
Общее мышление, которое должен иметь современный разработчик C ++, - это такое, которое больше фокусируется на изменчивых и неизменяемых и взаимодействует с необработанными типами и данными.
Когда мыпосмотрите на такую функцию:
void f(int x);
... разработчик C ++ сразу скажет вам, что для ввода используется «x».Зачем?Это передается по значению.Не существует способа изменить 'x' так, чтобы это оказало какое-либо влияние на вызывающего, и, следовательно, любой аргумент, переданный этой функции, не будет изменен.
Это также верно для любой ссылки на const:
void f(const Foo& read_only_foo);
Выше определенно является строгим входным параметром.Когда мы смотрим на такую функцию:
void f(int& x);
Обычно мы можем предположить, что f
собирается изменить x
(это не гарантируется, но знание того, что делает f
, должно устранить любые сомнения).
С пользовательскими типами он становится немного более туманным.
ostream& operator<<(ostream& os, const Foo& foo);
Здесь мы точно знаем, что 'foo' является входным параметром, поскольку он неизменен.Но как насчет «ОС»?Это выходной параметр, вход, оба?В строгих процедурных языках выходной параметр обычно подразумевает, что параметр будет изменен, но мы также читаем из него здесь, так что это будет и то и другое.Хотя мы будем вызывать методы в 'os', которые влияют на его состояние, это не совсем то, что мы думаем о выходном параметре в процедурных языках, которые изначально поддерживают параметры ввода / вывода.
Дело в том,что такой строгий подход к вводу-выводу о параметрах может привести к путанице с этими высокоуровневыми интерфейсами и объектно-ориентированным проектированием.Более полезный способ взглянуть на вещи здесь, как правило, заключается в том, является ли объект, реализующий интерфейс, изменчивым или неизменным.Здесь 'os' является изменчивым.Функция обычно говорит, что она будет вызывать некоторые функции, которые изменяют ее состояние.
Как насчет этого?
// fills the specified list with stuff
void some_list(list<int>& out_list);
Здесь она имеет тенденцию идти, возможно, более естественно, квид семантики мы ожидаем от выходного параметра.Что-то наподобие заполнения списка, мы склонны думать об этом более интуитивно, как о функции, выводящей результат через список.Я даже добавил к имени «out», чтобы подчеркнуть это.Но на самом деле, и особенно с C ++ 11, мы не должны писать такие вещи, как подчеркивает Страуструп:
// returns a new list filled with stuff
list<int> some_list();
Это фактически оставляет очень мало мест, где различие входа / выхода может быть очень полезнымвообще (и не избыточно с уже предоставленными средствами для пометки параметров как изменяемых / неизменяемых, по значению, ссылке, указателю или ссылке r-значения).
В сочетании с четкой документацией о том, что делает функция,как правило, нет никакой двусмысленности относительно того, как он работает со своими параметрами, поэтому соглашения о входе / выходе имеют тенденцию делать очень мало, но добавляют много дополнительного кода и могут способствовать формированию более ориентированного на данные мышления, от которого вы должны пытаться уйти.
В общем, я бы посоветовал попытаться избежать этого соглашения все вместе.Даже если есть веские аргументы в пользу этого, это просто не то, что люди склонны делать в C ++.И если вы хотите, чтобы люди получали удовольствие от работы с вашим кодом и не расстраивались, вы должны научиться понимать, что обычные массы склонны понимать и любить.Все, что слишком экзотично, отпугнет людей.
Если вы абсолютно, фанатично привязаны к тому, чтобы обозначать все как в или в , я рекомендую минимально навязчивое решение, такое какстиль документации или соглашение об именах.Определенно избегайте макросов, которые ничего не делают.Это потребует от ваших читателей проверки каждый раз, когда эти макросы действительно ничего не делают.Соглашение об именах или стиль документации не требуют такой проверки.
Наконец, небольшая цитата от самого создателя C ++:
Первое правило, касающееся макросов: не используйте их без необходимости.
Почти каждый макрос демонстрирует недостаток в языке программирования, в
в программе или в программаторе. - Бьярне Страуструп