|
Программирование >> Аргументация конструирования
добавляем новый курс semesterHours += hours; weighteoGPA += grade * hours; cpa = weightedGPA / semesterHours; вернуть новую оценку return gpa; Встраиваемые функции-члены Функция-член, определенная непосредственно внутри класса, по умолчанию считается встраиваемой (подставляемой, inline) функцией (если только не оговорено обратное, например с помощью опций командной строки компилятора). Функции- члены по умолчанию считаются inline-функциями, потому что большинство функ- j ций-членов, определенных внутри класса, довольно малы, а такие маленькие функции являются главными кандидатами на подстановку. Тело inJuгe-фyнкции подставляется компилятором пепосредствеппо вместо опера- тора ее вызова. Подставляемая функция выполняется быстрее, поскольку от процессора не требуется осуществлять переход к телу функции. Однако при этом программы, использующие встроеппые функции, занимают больще места, по- i скольку копии таких inline-функдий определяются один-единственный раз, а под- \ ставляются вместо каждого вызова. Есть еще одна техническая причина, по которой функции-члены класса лучше де- \ лать inline-функциями. Как вы помните, все структуры языка С обычно определя-i; ются в составе включаемых файлов с последующим использованием в исходных . с-файлах при необходимости. Такие включаемые файлы не должны содержать данных или тел функций, поскольку могут быть скомпилированы несколько раз. Использование же подставляемых функций во включаемых файлах вполне допустимо, поскольку их тела, как и макросы, подставляются вместо вызова в исходном файле. То же относится и к классам С+ + . Полагая функции-члены, определенные i j в описании классов, inline-функциями, мы избегаем описапной проблемы много- ! i кратной компиляции. = i.V.-.. . i Onfteqexenue функций-членов €не класса Для больших функций встраивание тела функции непосредственно в определение класса может привести к созданию очень больших и неудобочитаемых определений классов. Чтобы избежать этого, C++ предоставляет возможность определять тела функций-членов вне класса. Реализовать тело функции вне класса Student можно, например, так: class Student ( public: int semesterHours; float; gpa; добавить пройденный курс к записи float addCourse(int hours, float grade) Добавляет информацию о пройденном курсе к полям класса Student float Student::addCourse(int hours, float grade) [ float weightedGPA; weightedGPA erHours * gpa; добавить новый курс semesterHours += hours; weightedGPA += grade * hours; gpa = weightedGPA / semesterHours; return gpa; Теперь объявление класса содержит только прототип функции addCourse (). При этом само тело функции находится в другом месте. Объявление прототипа функции-члена по структуре не отличается от объявления прототипа любой другой функции, и, подобно всем объявлениям прототипов, обязательно. В этом примере класс Student и функция Student: :addCourse () определены в одном файле. Так можно делать, но такое расположение не очень распространено. Обычно класс Student определяется во включаемом файле, например а тело функции может находиться в отдельном исходном файле, например Student.срр. Фай ent. срр должен быть включен в состав вашего проекта вместе с другими файлами. Student.срр будет скомпилирован в отдельный .obj-файл, который затем будет скомпонован с другими файлами в вашу программу на этапе сборки. Более детальное описание этого процесса можно найти в главе 6, Создание функций . Функции-члены могут перегружаться так же, как и обычные функции (обратитесь к главе 6, Создание функций , если забтли, что это значит). Как вы помните, имя класса является частью полного имени, и все приведенные ниже функции вполне корректны. class Student public: grade - возвращает текущую среднюю оценку ffoat grade(); grade - устанавливает новое значение оценки и возвращает предыдущее float grade(float newGPA) ; II , прочие данные .. . class Slope { public: grade - возвращает снижение оценки float grade () ; .,.прочие члены-данные... grade - возвращаем млькый эквивалент оценки char grade{float value); int main(int argcs, char* рАгдз[]) Student s; 3.grade(3.5); Student::crade{float) float v = s . grad nr : :grade ( ) char с :: grade (float) Slope o; float m = о.grade 0 ; Slope::grade{) return 0; Полные имена вызываемых из main () функций указаны в комментариях. Когда происходит вызов функции, составляющими ее полного имени считаются не только аргументы функции, но и тип объекта, который вызывает функцию (если она вызывается объектом). Такой подход позволяет устранить неоднозначность при вызове функции. В нриведенном примере первые два вызова обращаются к функциям-членам Student: :grade (float) И Student: :grade () соответственно. Эти функции отличаются снисками аргументов. Вызов функции s.grade () обращается к Student: : grade () , поскольку тин объекта s - Student. Третья вызываемая функция в данном примере- функция : :grade (float), не имеющая вызывающего объекта. Последний вызов осуществляется объектом типа Slope, и соответственно вызывается функция-член Slope : : grade (float).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |