Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Объявление функции вне и внутри тела классаСодержание книги
Поиск на нашем сайте
При объявлении функции вне класса, внутри тела класса помещается только прототип или описание функции Все экземпляры (объекты) класса будут использовать один код функции, компилятор будет генерировать код для вызова функции при каждом обращении к функции. При полном объявлении функции внутри класса функция по умолчанию считается подставляемой, т.е. при каждом вызове этих функций их код “встраивается“ в точку вызова. Это, так называемые, inline-функции. Вместо команд передачи управления единственному экземпляру тела функции компилятор в каждое место вызова функции помещает команды кода операторов тела функции. Это может увеличить скорость выполнения программы, но увеличивает также размер кода программы. Если метод (функция) большой по объему, не следует настраивать компилятор на генерацию встроенного кода и следует объявить функцию вне класса, используя квалифицированное имя функции. Например. class Men { char * name; …
void setName (char*); //-функция- член класса … };
void Men:: setName (char*n) { name = n;}
Доступность компонентов класса В рассмотренных ранее примерах классов (date и complex) компоненты классов являются общедоступными (в классах с ключом struct или union компоненты общедоступны по умолчанию). В любом месте программы, где “видно” определение класса, можно получить доступ к компонентам объекта класса. Тем самым не выполняется основной принцип абстракции данных – инкапсуляция (сокрытие) данных внутри объекта. Для изменения видимости компонент в определении класса можно использовать спецификаторы доступа: public, private, protected. Общедоступные (public) компоненты доступны в любой части программы. Они могут использоваться любой функцией как внутри данного класса, так и вне его. Доступ извне осуществляется через имя объекта: имя_объекта.имя_члена_класса ссылка_на_объект.имя_члена_класса указатель_на_объект->имя_члена_класса Собственные (private) компоненты локализованы в классе и не доступны извне. Они могут использоваться функциями – членами данного класса и функциями – “друзьями” того класса, в котором они описаны. Защищенные (protected) компоненты доступны внутри класса и в производных классах. Изменить статус доступа к компонентам класса можно и с помощью использования в определении класса ключевого слова class. В этом случае все компоненты класса по умолчанию являются собственными.
Пример. class complex { double re, im; // private по умолчанию public:
double real(){return re;} double imag(){return im;}
void set(double x,double y){re = x; im = y;} };
Конструктор Недостатком рассмотренных ранее классов является отсутствие автоматической инициализации создаваемых объектов. Для инициализации объектов класса в его определение можно явно включить специальную компонентную функцию, называемую конструктором. Имя этой компонентной функции по правилам языка С++ должно совпадать с именем класса. Такая функция автоматически вызывается при определении или размещении в памяти с помощью оператора new каждого объекта класса.
Формат определения конструктора следующий: имя_класса (список_формальных_параметров) { операторы_тела_конструктора } Пример. сomplex(double re1 = 0.0,double im1 = 0.0){re = re1; im = im1;}
Конструктор инициализирует данные - члены класса. Конструктор явно или неявно вызывается при определении (или размещении в памяти с помощью операции new) каждого объекта класса. Основное назначение конструктора - превращение участка памяти в объект класса, т.е. инициализация его полей данных Конструктор имеет ряд особенностей: - Для конструктора не определяется тип возвращаемого значения. Даже тип void не допустим. - Указатель “на конструктор” не может быть определен, и соответственно нельзя получить адрес конструктора. - Конструкторы не наследуются. - Конструкторы не могут быть описаны с ключевыми словами virtual, static, const, mutable, volatile. - Конструктор всегда существует для любого класса, причем, если он не определен явно, он создается автоматически. По умолчанию создается конструктор без параметров и конструктор копирования. Если конструктор описан явно, то конструктор по умолчанию не создается. По умолчанию конструкторы создаются общедоступными (public). - Параметром конструктора не может быть его собственный класс, но может быть ссылка на него (T&). - Без явного указания программиста конструктор всегда автоматически вызывается при определении (создании) объекта. В этом случае вызывается конструктор без параметров. - Для явного вызова конструктора используются две формы: 1) имя_класса имя_объекта (фактические_параметры); 2) имя_класса (фактические_параметры);
Первая форма допускается только при не пустом списке фактических параметров. Она предусматривает вызов конструктора при определении нового объекта данного класса: complex ss (5.9,0.15); Вторая форма вызова приводит к созданию объекта без имени: complex ss = complex (5.9,0.15); Существуют два способа инициализации данных объекта с помощью конструктора:
Первый способ - передача значений параметров в тело конструктора. Второй способ предусматривает применение списка инициализаторов данного класса.
Этот список помещается между списком параметров и телом конструктора, отделенный от последнего разделителем ‘: ‘ (двоеточие). Каждый инициализатор списка относится к конкретному компоненту и имеет вид: имя_данного (выражение). Инициализаторы полей отделяются друг от друга запятыми.
Примеры. class CLASS_A { int i; float e; char c; public: CLASS_A(int ii,float ee,char cc): i(8),e(i * ee + ii),с(сс){}...}; Класс “символьная строка”: #include <cstring> #include <iostream> using namespace std; class string { char *ch; // указатель на текстовую строку int len; // длина текстовой строки public: конструкторы создается объект – пустая строка string(int N = 80): len(0){ch = new char[N+1]; ch[0] = ‘\0’;} создается объект по заданной строке string(const char *arch){len = strlen(arch); ch = new char[len+1]; strcpy(ch,arch);} компоненты-функции возвращает ссылку на длину строки int& len_str(void){return len;} возвращает указатель на строку char *str(void){return ch;}...};
Здесь у класса string два конструктора – перегружаемые функции. По умолчанию в любом классе T создается также конструктор копирования вида: T::T(const T&), где Т – имя класса. Конструктор копирования вызывается всякий раз, когда выполняется копирование объектов, принадлежащих классу. В частности он вызывается: а) когда объект передается функции по значению; б) при построении временного объекта как возвращаемого значения функции; в) при использовании объекта для инициализации другого объекта.
Если класс не содержит явным образом определенного конструктора копирования, то при возникновении одной из этих трех ситуаций производится побитовое копирование объекта (конструктор копирования по умолчанию). Побитовое копирование не во всех случаях является адекватным. Именно для таких случаев и необходимо определить собственный конструктор копирования. Обязательное его определение в тех случаях, когда класс содержит поля, являющиеся указателями на динамические участки памяти. Например, в классе string: string(const string& st) {len=strlen(st.len); ch=new char[len+1]; strcpy(ch,st.ch); }
|
||||
Последнее изменение этой страницы: 2021-02-07; просмотров: 167; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.35.234 (0.007 с.) |