КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Константные объекты и функции-члены
Инициализация переменных-членов в конструкторах При определении класса запрещается инициализировать переменные-члены. Так, следующее определение класса содержит ошибки. class С { private:int N = 0; //ОШИБКАconst int CInt = 5; //ОШИБКАint &RInt = N; //ОШИБКА//...};Инициализация переменных внутри определения класса бессмысленна, потому что определение класса задает всего лишь тип каждой из переменных-членов, но не резервирует для них реальную область памяти. Скорее всего, при написании программы требуется инициализировать переменные-члены каждый раз при описании экземпляра класса. Следовательно, целесообразно инициализировать переменные внутри конструктора класса. Конструктор класса CRectangle инициализирует переменные-члены, используя выражение присваивания. Однако определенным типам данных, в частности, константам и ссылкам, не могут быть присвоены значения. Чтобы эта проблема не возникала, в языке C++ предусмотрено специальное свойство конструктора, называемое списком инициализации, который позволяет инициализировать одну или более переменных, а не присваивать им значения. Список инициализации в определении конструктора помещается непосредственно после списка параметров. Он содержит двоеточие с последующим одним или несколькими инициализаторами полей, отделенными друг от друга запятыми. Инициализатор поля содержит имя переменной с последующим начальным значением в круглых скобках. Например, в приведенном ниже классе конструктор содержит список инициализации, который, в свою очередь, содержит инициализаторы полей для всех переменных класса. class С{private:int N;const int CInt;int &RInt;//... public:С (int Parm): N (Farm), CInt (5), RInt (N){// код конструктора...
Следующее определение создает объект, демонстрирующий применение списка инициализации, где переменные N и CInt инициализированы значениями 0 и 5, а переменная-член RInt – как ссылка на переменную N: С CObject (0);Как показано в гл. 2, добавление спецификатора const к определению переменной означает невозможность изменения ее значения. Аналогично, добавление спецификатора const в определение объекта класса означает, что нельзя изменять значения переменных, принадлежащих этому классу. Рассмотрим, например, класс class CTest {public:int A; int B;CTest (int AVal, int BVal); {A = AVal; В = BVal; } }Оператор создает объект этого класса и инициализирует обе переменные-члены const CTest Test (1, 2};Это первая и последняя возможность присвоить значения таким переменным. Из-за спецификатора const недопустимо присваивание Test.А =3; // ОШИБКА: нельзя изменять переменные-члены //Объекта типа constСуществуют и другие варианты объявления объекта с использованием спецификатора const. Чтобы продемонстрировать их, рассмотрим объявление объекта класса CRectangle, приведенного в этой главе. const CRectangle Rect (5, 5, 25, 25);Хотя функция-член GetCoord класса CRectangle не изменяет никаких переменных-членов, компилятор не позволит программе вызвать ее для объекта с атрибутом const. int L, Т, R, В;Rect.GetCoord (&L, &T, &R, &B); //ошибкаПоскольку обычная функция-член может изменить значение одной или нескольких переменных-членов, компилятор не позволяет вызвать функцию-член объекта типа const. Компилятор не имеет возможности проверить, модифицирует ли в действительности метод класса переменные-члены, так как реализация функции может находиться в отдельном файле исходного кода. Чтобы иметь возможность вызова функции GetCoord для объекта типа const, следует включить спецификатор const в определение функции. class CRectangle{//...void GetCoord (int *L6 int *T6 int *R, int *B) const{*L = Left; *T = Top; *R = Right; *B = Bottom; }//...};Спецификатор const в определении функции GetCoord означает, что функция не может изменять переменные-члены. Если она пытается это сделать, компилятор будет генерировать ошибку при компиляции исходного кода. Функцию GetCoord сейчас можно вызвать для объекта типа const класса CRectangle.
Кроме того, можно функцию-член Draw объявить как const, так как она не изменяет значений переменных. Очевидно, имеет смысл добавлять спецификатор const ко всем функциям-членам, которые не модифицируют поля класса, чтобы пользователь мог свободно вызывать такие функции для объектов типа const. Конечно, функцию, подобную CRectangle:: SetCoord, нельзя объявить как const. Инициализация объектов-членов класса. Можно определить переменную, являющуюся объектом другого класса, т. е. можно встроить объект одного класса в объект другого. Такие переменные называют объектами-членами или встроенными объектами. Его можно инициализировать, передавая требуемые параметры конструктору, помещенному в список инициализации конструктора класса, содержащего объект-член. Например, класс CContainer в следующем примере содержит объект-член класса CEmbedded, инициализируемый в конструкторе класса CContainer. class CEmbedded {//...public:CEmbedded (int Parml, int Parm2) {//... }//...};class CContainer{private:CEmbedded Embedded; public:CContainer (int PI, int P2, int P3): Embedded (PI, P2) {// код конструктора... }//... };Если объект-член не инициализирован в списке инициализации конструктора или если конструктор генерируется компилятором, то последний автоматически вызовет для объекта конструктор по умолчанию, если таковой имеется (вспомните: не каждый класс имеет конструктор по умолчанию). Если подобного рода конструктор отсутствует, то компилятор выдаст ошибку. Примечание Как будет показано в гл. 4, список инициализации можно также использовать внутри конструктора производного класса, чтобы передать значения в конструктор, принадлежащий базовому классу.
Дата добавления: 2014-01-07; Просмотров: 1293; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |