русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Виртуальные методы


Дата добавления: 2013-12-23; просмотров: 1701; Нарушение авторских прав


Статические члены класса

Дружественные классы

Дружественные члены класса

Методы-члены класса

В терминологии объектно-ориентированного программирования функции также называются методами или методами - членами класса, для того чтобы подчеркнуть, что конкретная функция является членом некоторого класса.

По стандарту ANSI С, используемому компилятором Visual С++, любая используемая в модуле компиляции функция должна иметь прототип, включающий в себя тип функции, имя функции и список параметров с их типами. Прототип - это некоторое предварительное описание функции, заканчивающееся символом ;.

Прототип функции должен быть вставлен во все модули компиляции, использующие функцию. Для небольших программ прототип функции обычно записывается в модуль компиляции. Для программ, создаваемых средствами Visual С++, и программ, состоящих из нескольких модулей, прототип функции указывается в заголовочном файле. Объявление функции должно однозначно соответствовать ее прототипу и может находиться в любом модуле компиляции (для которого доступен прототип функции).

Прототип метода, являющегося членом некоторого класса, записывается в заголовочном файле, содержащем объявление класса в теле этого класса.

Метод - член класса может иметь следующие модификаторы доступа:

• public - общедоступный метод;

• protected - метод, доступный только для членов и объектов данного класса и наследуемых классов (наследуемых с модификаторами доступа public или protected);

• private - защищенный метод, доступный только внутри класса.

Прототип метода может иметь следующее формальное описание:

Модификатор_доступа тип_метода имя_метода

(список_параметров);

Объявление метода может иметь следующее формальное описание: модификатор_доступа тип_метода имя_метода



{список_параметров)

{ тело_метода }

Тип метода является типом возвращаемого методом значения и может быть любым допустимым базовым или производным типом, включая и тип указателя.

Указатели типа void могут использоваться для объявления параметров метода в том случае, если тип этих параметров на момент компиляции неизвестен.

Например:

void Fx(void *pV); //Прототип метода

...

piVar=new int;

pfVar=new float;

Fx(piVar); // Вызов метода для

// параметра типа int

Fx(pfVar); // Вызов метода для

// параметра типа float

...

// Реализация метода

void Fx(void *pV) {*pV=12345;}

Метод, возвращающий указатель, записывается следующим образом:

тип *имя метода(список_параметров).

Список формальных параметров - это значения, передаваемые в функцию. Каждый элемент этого списка может иметь любой допустимый тип.

Язык С++ допускает передачу параметров по значению и по ссылке или указателю. Параметры, передаваемые по значению, при выполнении программы заносятся в стек, и для больших размеров структур или массивов может возникнуть ситуация переполнения стека. Параметры, передаваемые как ссылки или указатели, не копируются в стек.

Изменение значений самих параметров происходит только для параметров, переданных по ссылке или указателю. При передаче параметра по значению метод изменяет не сам параметр, а его копию.

Список параметров может включать параметры, имеющие значения по умолчанию. Такие параметры указываются в конце списка параметров. Значение по умолчанию будет использовано только в том случае, если число переданных параметров меньше числа указанных формальных параметров в описании метода.

Язык С++ разрешает рекурсивный вызов методов.

В методах класса можно использовать ключевое слово this, являющееся указателем на объект данного класса. Это ключевое слово нельзя использовать вне метода члена класса.

Создание метода-члена класса

Для того чтобы в среде Visual Studio .NET добавить в класс новый метод - член класса, следует в окне просмотра классов Class View выделить секцию с именем класса и выполнить команду контекстного меню Add |Add Function, а затем в диалоге - мастере построения метода ввести имя метода, его тип, а также определить список параметров.

При добавлении метода - члена класса в файл реализации класса автоматически добавляется код реализации нового метода, а в заголовочный файл - объявление этого метода.

Указатели на методы-члены класса и на функции

Указатели на методы и на функции могут быть использованы для передачи метода в качестве параметра другому методу.

Объявление указателя на метод может иметь следующее формальное описание: тип_метода (имя_класса::*имя_метода_указателя)

(список параметров);

тип_функции (*имя_функции_указателя)

(список параметров);

Инициализация указателя может иметь следующее формальное описание:

тип_метода имя_класса::*имя_метода указателя

(список параметров)=

&имя класса::имя любого метода;

тип_функции (*имя_ функции_указателя)

(список параметров)= &имя_функции;

Вызов метода, объявленного как указатель на метод, может быть выполнен следующим образом: (имя_объекта->*имя_ метода указателя)

(список параметров);

(*имя_ функции_указателя)(список параметров);

Для функций, но не для методов - членов класса, разрешена другая форма вызова метода: имя__ функции_указателя(список параметров);

(имя__ функции_указателя){список параметров);

Объявление функции, имеющей в качестве параметра указатель на метод, может иметь следующее формальное описание:

тип_метода имя_метода (тип_метода_указателя

(*имя_метода_указателя)

(список параметров));

Вызов метода, использующего в качестве параметра указатель на метод, может иметь следующее формальное описание:

имя_метода(имя_объекта->*имя_метода_указателя);

имя_функции(имя функции_указателя);

Разрешается создавать массив указателей на функции.

При использовании указателей на функцию можно не употреблять операцию разыменования или операцию получения адреса. Например:

class al

{

public:

al(void);

~al(void);

int Fxl(int i1);

int Fx2(int i2) ;

};

al::al(void){}

al::-al(void){}

int al::Fxl(int i1){ return 1;} int al::Fx2(int i2){ return 2;}

int (*Fy_pointer) ();

// Объявление указателя на функцию int Fy ();

int _main(int argc, char* argv[])

{

al* a1Object = new a1();

int (al::*Fx_pointer)(int)=&al::Fx2;

// Объявление и инициализация указателя

// на метод - член класса

int i ;

i=(alObject->*Fx_pointer)(1);

// Вызов по указателю на метод

Std::cout <<i;

int (*Fy_pointer)()=&Fy;

// Объявление и инициализация указателя

// на функцию

std: :cout<< (Fy_pointer) ()

std::cout<<(*Fy_pointer)();

// Вызов по указателю на

// функцию (две формы)

return 0;

}

int Fy () {return 5;}

Встроенные функции

Встроенные функции указываются оператором inline. Применение встроенных функций может несколько сократить время выполнения программы, так как компилятор встраивает код такой функции в том месте программы, где указан ее вызов. Например:

inline void Fx(void) {

std::cout<<"Функция Fx"<<std::endl;}

...

Fx(void);

// Этот код будет заменен компилятором // на код встроенной функции

Перегрузка функций и методов

Язык С++ позволяет выполнять перегрузку функций и методов - членов класса, то есть вызывать функцию (метод) с тем же именем, но с различными типами фактических параметров. Для создания перегружаемой функции следует указать отдельный прототип и сделать отдельное объявление для каждого списка параметров. Если функции различаются только типом и имеют совпадающие списки параметров, то для таких функций перегрузка не допускается.

Для определения вызываемой перегружаемой функции учитываются только списки параметров, а тип возвращаемого значения не учитывается. При этом для соответствия списка параметров вызываемой функции может применяться преобразование типов и соответствие по многоточию для функций с переменным числом параметров.

Дружественные члены класса (методы) позволяют получить доступ к защищенным модификатором private членам класса из методов других классов. Методы и классы, объявляемые дружественными, иногда также называются друзьями класса.

Если метод класса а внутри тела класса в объявляется с модификатором friend, что указывает на то, что он является другом класса, то из него разрешен доступ ко всем членам класса в. Например:

class А { public: int Fx();}

class В { public: friend int A::Fx();

private:

}

 

Объявление дружественного класса позволяет всем его методам получить доступ ко всем переменным и методам другого класса. Например:

class A {public: int Fx();}

class В {public:

friend class A;

private:

}

Дружественный класс или член класса будет доступен только в том случае, если он был объявлен в области видимости самого класса или ранее во внешней области видимости, внутри которой располагается область видимости, содержащая объявление класса с объявлениями друзей класса. Например:

class A {public:

// Класс расположен во внешней

// области видимости

int Fxl();

}

namespace classB { class В {public:

friend class A; friend class C; private:

}

class С { public:

// Класс расположен в том же

// пространстве имен

int Fx2 () ;

}

}

Дружественные классы не наследуются, и их дружественность не является транзитивной. Например:

class А {int Fx();}

class В. (friend class A;}

class С {friend class B;}

// Класс А не является

// дружественным классу С

class D : public В {}

// Класс А не является

// дружественным классу D

Переменные и члены класса, объявленные с модификатором доступа static, называются статическими членами класса. Статические переменные и методы доступны без создания объекта данного класса. Имя статической переменной квалифицируется именем класса с использованием операции принадлежности :: , а не именем экземпляра класса. Например:

class А { public: static int iStat; };

int main(int argc, char* argv [] ) {

A:: iStat = 123;

}

Статические методы могут вызывать и использовать только другие статические методы и статические переменные. Из статического метода нельзя выполнять вызов не статического метода - члена класса.

Статическую переменную можно рассматривать как аналог глобальной переменной, которая связана с конкретным классом.

Часто статические переменные называют переменными класса, а не статические переменные переменными экземпляра.

Для статических переменных могут использоваться указатели. Например:

class А { public:

static int iStatVar;

};

int main(int argc, char* argv[]){

int A:: iStatVar = 0;

int *piStatVar = &A:: iStatVar;

}

При использовании статических переменных указатели всегда являются указателями на существующий тип (в данном примере на тип int), а не на тип класса.

Для того чтобы создать и использовать статическую переменную, следует:

1. Объявить (как правило, в заголовочном файле) статическую переменную как член класса.

Например: static int iStat;.

2. Для выделения памяти под эту переменную ее повторно следует объявить в модуле компиляции, в котором она будет использоваться, квалифицируя имя статической переменной именем класса.

Например: int A::iStat;

3. Выполнить инициализацию статической переменной (по умолчанию статическая переменная типа int имеет значение 0).

Например: A: :iStat=123;

Инициализацию статической переменной можно выполнять в теле конструктора в том случае, если при создании объекта с использованием этого конструктора память под статическую переменную уже выделена. Однако инициализировать статическую переменную через конструктор в форме

имя_класса::имя_конструктора :

имя_стат переменной(значение) { }

нельзя ни в каком случае.

Для того чтобы создать статический метод - член класса в среде Visual С++, достаточно выделить в окне class view секцию с именем класса, в который будет вставлен создаваемый метод, и выполнить команду контекстного меню Add|Add Function. А затем определить тип и имя создаваемого метода, список параметров, и отметить флажок static, указывающий на то, что создаваемая функция будет статической.-

В результате выполненных действий среда Visual С++ добавит в заголовочный файл класса прототип создаваемой статической функции, а в файл реализации - код реализации создаваемой статической функции.

Например:

class a1

{public:

al(void);

~al(void);

int Fxl(int il);

int Fx2(int i2);

protected:

static int Fstatl(void);

// Статическая функция доступна

//только для статических методов - членов

//данного класса и наследуемых классов

public:

static int Fstat2(void);

// Общедоступная статическая функция

};

int main(int argc, char* argv[]){ Std::cout<<a1::Fstat2();

// Вызов статической функции

}

Реализация статической функции записывается так же, как и реализация любого другого метода - члена класса. При этом ключевое слово static не указывается. Например:

int А::FStatl(void) { return 0; }

 

Виртуальные методы объявляются в базовом классе с ключевым словом virtual, а в производном классе могут быть переопределены. Прототипы виртуальных методов как в базовом, так и в производном классе должны быть одинаковы.

Применение виртуальных методов позволяет реализовывать механизм позднего связывания, при котором определение вызываемого метода происходит на этапе выполнения, а не на этапе компиляции. При этом вызываемый виртуальный метод зависит от типа объекта, для которого он вызывается. При раннем связывании, используемом для не виртуальных методов, определение вызываемого метода происходит на этапе компиляции.

На этапе компиляции строится таблица виртуальных методов, а конкретный адрес проставляется уже на этапе выполнения.

При вызове метода с использованием указателя на класс действуют следующие правила:

• для виртуального метода вызывается метод, соответствующий типу объекта, на который указывает указатель.

• для не виртуального метода вызывается метод, соответствующий типу самого указателя. В следующем примере иллюстрируется вызов виртуальных методов:

class А // Объявление базового класса

{ public:

virtual void VirtMetod1(); // Виртуальный метод

void Metod2(); // He виртуальный метод

};

void A::VirtMetod() { cout << Вызван A:: VirtMetod1\n";}

void A::Metod2() { cout << "Вызван A: :Metod2\n"; }

class В : public A // Объявление производного класса

{public:

void VirtMetod1(); // Виртуальный метод

void Metod2(); // He виртуальный метод

};

void В::VirtMetod1() { cout << "B::VirtMetod1\n";}

void B::Metod2() { cout << "B::Metod2\n"; }

void main() {

В aB; // Объект класса В

В *рВ = &аВ; // Указатель на объект класса В

А *рА = &аВ; // Указатель на объект класса А

pA->Vi.rtMetodl () ; // Вызов метода VirtMetod класса В

pB->VirtMetodl(); // Вызов метода VirtMetod класса В pA->Metod2(); // Вызов метода Metod2 класса А

pB->Metod2(); // Вызов метода Metod2 класса В

}

Результатом выполнения этой программы будут следующие строки:

Вызван В::VirtMetodl

Вызван В::VirtMetodl

Вызван A::Metod2

Вызван В::Metod2

Чисто виртуальной функцией называется виртуальная функция, указанная с инициализатором = 0.

Например:

virtual void F1( int) =0;

Объявление класса может содержать виртуальный деструктор, используемый для удаления объекта определенного типа. Однако виртуального конструктора в языке С++ не существует. Некоторой альтернативой, позволяющей создавать объекты заданного типа, могут служить виртуальные методы, в которых выполняется вызов конструктора для создания объекта данного класса. Например:

class а{

public:

А() ;

A (const А&);

virtual A* virt_objectl () {

return new А() ;

}

virtual A* virt_object2 () {

return new A{*this);

}

}



<== предыдущая лекция | следующая лекция ==>
Преобразование объектных типов | Условный оператор if.


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.011 сек.