|
Программирование >> Аргументация конструирования
spmesterHours += hours; lit main (int argcs, * pArgs [ ]) ?...c.ddCourse(3, 4.0); Поставим ему 4 балла t. addCourse (3, 2.5); a этому дадим 2 с пшосом... return 0; Когда addCourse () вызывается для объекта s, все сокращенные имена в теле этой функции считаются членами объекта s. Таким образом, обращение к неременной semesterHours внутри функции s . addCourse () в действительности является обращением к переменной s. semesterHours, а обращение к gpa - обращением к s.gpa. В следующей строке функции main (), когда addCourse () вызывается для объекта t того же класса Student, нроисходит обращение к членам класса t t.semesterHours и t.gpa. Именование текущего объекта Как функция-член определяет, какой объект является текущим? Это не магия и не шаманство - просто адрес этого объекта всегда передается функции-члену как. скрытый первый аргумент. Другими словами, при вызове функции-члена происходит цреобразование такого вида: S.addCourse(3,2.5} равносильно Student::addCourse(&s, 3,2.5) (команда, приведенная в правой части выражения, синтаксически неверна; это просто изображение того, как компилятор видит выражение в левой части во внутреннем представлении). Соответственно внутри функции, когда нужно узнать, какой именно объект является текущим, используется этот указатель. Тип текущего объекта указатель на объект соответствующего класса. Всякий раз, когда функция-член обращается к другому члену класса, не называя имени его объекта явно, компилятор считает, что данный член является членом этого (this) объекта. При желании вы можете явно обращаться к членам этого объекта, используя ключевое слово this. Так что функцию Student: : addCourse () можно переписать следующим образом: floa dCourse(int hours, float grade)- { float weightedGPA; . . weightedGPA = this->semesterHours * this->gpa; добавим новый курс this->seme3terHours hours; weightedGPA += hours * grade; . thrs->gpa = weightedGPA / this->semesterHours; returnthis->gpa; Независимо от того, добавите ли вы оператор this-> в тело функции явно или нет, результат будет одинаков. Объект, для которого вызывается функция-член, называется текущим , и все имена членов, записанные в сокращенном виде внутри счи- таются членами текущего обьекта. Другими словами, сокращенное обращение к членам класса интерпретируется как обращение к членам текущего объекта. TasfteuieHue о6лааШ1 €uquMOCfEu Символ : : между именем класса и именем его члена называют оператором разрешения области видимости, поскольку он указывает, какой области видимости принадлежит член класса. Имя класса перед двоеточиями похоже на фамилию, тогда как название функции после двоеточия схоже с именем - такой порядок записи принят на востоке. Оператор : : можно использовать и для описания функции - не члена, вав для этого пустое имя класса. В этом случае функция addCourse () должна быть описана как : float). Обычно оператор : : не обязателен, однако в некоторых ситуациях это не так. Рассмотрим следующий фрагмент кода: ourse - перемножает количество часов и оценку float adcCoursedn hours, float grade) return hours*grade; class Student { public: float gpa; дсбавить пройденный курс к записи float addCourseUnt hours, float grade) < вызвать внешнюю функцию v.-eightedGPA = addCourse (semesterHours, gpa) ; вызвать ту же функцию для подсчета оценки с учетом нового курса v.eightedGPA addCourse (hours, grade) ; gpa = weightedGPA / semesterHours; вернуть новую оценку return gpa; В этом фрагменте я хотел, чтобы функция-член Student: () вызывала функцию - ne член : : addCourse (). Без оператора : : вызов функции addCourse О внутри класса Student Приведет К вызову функции Student: : addCourse () . Функция-член может использовать для обращения к другому члену класса сокращенное имя, подразумевающее использование имени текущего экземпляра класса. В данном случае вызов функции без указания имени класса приводит к тому, что она вызывает саму себя. Добавление оператора : : в начале имени заставляет осуществить вызов глобальной версии этой функции (что нам и нужно): ourse - количество часов и оценку float addCourse(in hours, float grade) return hours*grade; class Student [ public: int semesterHours; float gpa; добавить пройденный курс к записи float addCourse(int hours, float grade) вызвать внешнюю функцию weightedGPA = ::addCour3e(semesterHours, gpa); вызвать ту же функцию для подсчета оценки с учетом нового курса weightedGPA += ::addCourse(hours, grade); gpa = weightedGPA / seiriesterHcurs; вернуть новую сценку return gpa; Это похоже на то, как если бы я звал Стефана в собственное доме. Все решили бы, что я зову самого себя: ведь в моем доме, естественно, подразумевается фамилия Дэвис. Если же я имею в виду какого-то другого Стефана, то должен сказать Стефан Спупендайк или Стефан Мак-Суини либо использовать какую-нибудь другую фамилию. Так же действует и оператор разрешения области видимости. Расширенное имя функции включает в себя ее аргументы. Теперь же мы добавляем к полному имени еще и имя класса, к которому принадлежит функция. Onfteqe4£Hue функции-члена Функция-член может быть определена как внутри класса, так и отдельно от него. Когда функция определяется внутри класса, это выглядит так же, как и в файле student . h: class Student public: int semesterHours ; float gpa; добавляем пройденный курс к записи float addCourse(int hours, float grade) { подсчитываем суммарное время курсов с учетом среднего балла float weightedGPA; weightedGPA = semesterHours * gpa;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |