Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Cout « x.GetCO; // Отображает статический член сСодержание книги
Поиск на нашем сайте
Размещение объектов по заданным адресам Иногда вам может понадобиться поместить объект в заданный участок памяти, например, в глобальный буфер в сегменте данных. Подобные объекты продолжают существовать и вне области их объявления, и иногда их называют "постоянными объектами". В листинге 15.15 демонстрируется размещение объекта по заданному адресу. В программе также приводится пример непосредственного вызова деструктора — необычный прием, который может пригодиться для удаления объектов, созданных перегруженным оператором new, использующим нестандартные способы выделения памяти. «include <iostream.h> Class TPersist { Privet: Int x,y; Public: TPersist(int a, int b) { x = а; у = b; } ~TPersistO { x = 0; у = 0; } void *operator new(size_t, void *p) { return p; } friend ostream& operator<< (ostream &os, TPersist &p); }; char object[sizeof(TPersist)]; main() { TPersist *p = new(object) TPersist(10, 20); cout «*p «endl; cout «"Address of object == " «&object «endl; cout << "Address of *p == " «&(«p) «endl; p->TPersist::~TPersist(); p->~TPersist(); // Непосредственный вызов деструктора return 0; // Можно в ВС++ версии 4.0; нельзя в 3.1 } ostream& operator«(ostream& os, TPersist &p) { os << "x == " << p.x «", у == " «p.у; return os; } В классе TPersist оператор new перегружается необычным способом. Вместо того чтобы выделить память для указателя, функция перегрузки оператора просто возвращает указатель р типа void. В программе в строке 17 оператор new используется для сохранения объекта класса TPersist в глобальном буфере, определенном в строке 13. Выражение new(object) вызывает перегруженную функцию-член оператора, передавая ей адреса символьного буфера object. Поскольку перегруженный оператор new просто возвращает переданный ему указатель р, этот несколько странно выглядящий оператор в действительности присваивает указателю р адрес объекта, а также вызывает конструктор класса TPersist для инициализации нового, выделенного в буфере объекта. В программе отображаются адреса символьного буфера object и объекта в буфере. Эти адреса идентичны, что свидетельствует о размещении объекта в указанном месте. Неплохим упражнением будет запуск PERSIST из отладчика Turbo Debugger. Проследите за содержимым буфера object во время пошагового выполнения кода с помощью клавиши <F8>. После выполнения строки 17 вы увидите, что в глобальном буфере появились значения 10 и 20; это доказывает, что перегруженный оператор new не пользовался стандартными средствами выделения памяти в куче. В строке 21 вызывается деструктор класса для объекта, адресуемого р. Поскольку объект содержится в глобальной переменной, может возникнуть необходимость в вызове деструктора именно таким способом для выполнения действий по очистке объекта. Для невиртуальных деструкторов следует использовать приводящийся в листинге оператор следующего вида: p->TPersist:: TPersistO; // Непосредственный вызов деструктора C++ не распознает область действия объекта, сохраненного в буфере, и не может вызвать деструктор класса автоматически. Опять же, будет весьма поучительно выполнить этот оператор из Turbo Debugger. Если вы это сделаете, то увидите, как встраиваемые в код операторы деструктора обнуляют данные-члены объекта (строки 8 и 21). Для виртуальных деструкторов, даже в случае с объектами производных классов, можно использовать следующую форму вызова деструктора: p->~TPersist(); // Непосредственный вызов деструктора В Borland C++ 3.1 подобное упрощение синтаксиса запрещено. Инициализация членов Объекта класса В конструкторе обычно инициализируются данные-члены объекта класса. Например, в классе TAnyClass объявляются два целочисленных данных-члена х и у, инициализирующихся с помощью операторов присваивания во встраиваемом конструкторе: class TAnyClass { Private: i int x, у; public: TAnyClass(){x=0,y=0} …….. }; В качестве альтернативы вы можете инициализировать члены так, как если бы они имели конструкторы: class TAnyClass { private: int x, у; public: TAnyClassO: x(0), y(0) { } }; В этой версии конструктора TAnyClass членам х и у присваиваются нулевые значения аналогично тому, как это делалось с помощью присваиваний в предыдущем примере. Скомпилированный код один и тот же для обоих фрагментов, однако во втором случае инициализаторы данных-членов задаются до выполнения тела конструктора. (В данном случае тело конструктора пустое.) Этот прием особенно полезен для инициализации объектов других классов. Например, предположим, что класс TAnyClass имеет член-объект класса TNewClass и конструктору класса TNewClass необходим один целочисленный параметр: class TNewClass { int x; public: TNewClass(int n) { x = n; } Если в классе TAnyClass объявляется член типа TNewClass, конструктор TAnyClass обязан инициализировать этот объект. Поскольку конструктор не может быть вызван непосредственно, объект должен инициализироваться с помощью альтернативного способа, описанного ранее: class TAnyClass { private: int x; TAnyClass(int n): z(n) { x = n; } ….. };
Член класса х, как и раньше, имеет тип int. Член z — объект класса TNewClass. Конструктор класса TAnyClass объявляется с целочисленным параметром п, использующимся для инициализации z перед выполнением тела конструктора. Внутри конструктора с помощью присваивания значение п запоминается в члене х. Если в классе имеется несколько объектов-членов, вы можете инициализировать их, перечислив и разделив запятыми, следующим образом:
TNewClass a, b, z; // Три объекта-члена класса Privat: Int x; TNewClass z; public: TAnyClass(int n): a(n), b(n), z(n) // Инициализация a, b и z { x = n; // Инициализация х ….. };
|
||||
Последнее изменение этой страницы: 2016-08-01; просмотров: 205; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.12.0 (0.012 с.) |