Цель прототипа функции в C ++ - сообщить компилятору
- как называется функция,
- что это за типы аргументов и
- какой тип (если есть) он возвращает.
Важной деталью здесь является то, что вышеприведенный список не включает имена параметров. Например, все следующие фрагменты кода объявляют одну и ту же функцию:
int myFunction(int a, double b);
int myFunction(int apples, double bananas);
int myFunction(int pizkwat, double zyzzyzyplyz);
Более того, фактическая реализация myFunction
не потребует использования каких-либо имен, приведенных здесь. Например, мы могли бы написать
int myFunction(int snickerdoodle, double alfajores) {
// ... do something ... //
}
и компилятор был бы совершенно доволен этим, даже если ни один из вышеперечисленных прототипов не использовал эти имена.
Теперь, для странного мелочи в C ++: в C ++ возможно объявить функции, у которых есть параметры, у которых нет имен. Например, этот код совершенно легален:
void doSomething(int) {
// This function takes in an integer. You can't call it without
// passing in that integer. However, this function has no way of
// referencing its argument, because it doesn't have a name!
}
Вы видите, что это используется на практике. Например, перегрузка оператора постфикса ++
требует объявления функции с именем operator++
, которая принимает int
, значение которого по существу никогда не используется. Или, возможно, вы переопределяете функцию в производном классе и вам не нужно использовать предоставленные аргументы.
Это означает, что у нас есть три правила в C ++:
Правило одно : имена параметров в прототипах функций игнорируются.
Правило два : Реализация функции не должна выбирать для своих параметров те же имена, что и у ее прототипа.
Правило три : у параметров вообще не должно быть имен.
Комбинируя эти три правила вместе, вы иногда видите такие вещи:
int myFunction(int, double); // Prototype gives no names to arguments
int myFunction(int a, double b) {
// .. use parameters a and b ... //
}
Здесь прототип функции не дает имен своим параметрам, но это нормально! C ++ все еще изучает все, что нужно о функции (имя, тип возвращаемого значения и типы аргумента). Это законно из-за первого правила и третьего правила. В реализации, которая действительно должна ссылаться на параметры, этим параметрам присваиваются имена a
и b
. Тот факт, что эти параметры теперь имеют имена, вполне подходит из-за второго правила.
Итак, возвращаясь к вашему примеру, прототип функции
string ltrim(const string &);
означает «Я объявляю функцию с именем ltrim
. Она принимает ссылку на const string
и возвращает string
». Это полностью эквивалентно высказыванию
string ltrim(const string& toTrim);
или
string ltrim(const string& oompaLoompa);
Фактическая реализация ltrim
, судя по всему, почти наверняка назовет свой параметр, чтобы он мог ссылаться на него и обрезать строку.
Надеюсь, это поможет!