учебники, программирование, основы, введение в,

 

C++: статические члены класса и виртуальные функции

Статические члены класса
Переменные и члены класса, объявленные с модификатором доступа static, называются статическими членами класса. Cтатические переменные и методы доступны без создания объекта данного класса. Имя статической переменной квалифицируется именем класса с использованием операции принадлежности :: , а не именем экземпляра класса.
Например:
class A { public: static int iStat; };
int main(int argc, char* argv[]) {
A:: iStat = 123;
}
Статические методы могут вызывать и использовать только другие статические методы и статические переменные. Из статического метода нельзя выполнять вызов не статического метода - члена класса.
Статическую переменную можно рассматривать как аналог глобальной переменной, которая связана с конкретным классом.
Часто статические переменные называют переменными класса, а не статические переменные - переменными экземпляра.
Для статических переменных могут использоваться указатели.
Например:
class A
{ public:
static int iStatVar;
};
int main(int argc, char* argv[]){
int A:: iStatVar = 0;
int *piStatVar = &A:: iStatVar;
}
При использовании статических переменных указатели всегда являются указателями на существующий тип (в данном примере на тип int), а не на тип класса.
Для того чтобы создать и использовать статическую переменную, следует:

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

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

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

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

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

Например: A::iStat=123;
Инициализацию статической переменной можно выполнять в теле конструктора в том случае, если при создании объекта с использованием этого конструктора память под статическую переменную уже выделена. Однако инициализировать статическую переменную через конструктор в форме
имя_класса::имя_конструктора :
имя_стат_переменной(значение) { }
нельзя ни в каком случае.
Для того чтобы создать статический метод - член класса в среде Visual C++, достаточно выделить в окне Class View секцию с именем класса, в который будет вставлен создаваемый метод, и выполнить команду контекстного меню Add|Add Function. А затем определить тип и имя создаваемого метода, список параметров, и отметить флажок Static, указывающий на то, что создаваемая функция будет статической.
В результате выполненных действий среда Visual C++ добавит в заголовочный файл класса прототип создаваемой статической функции, а в файл реализации - код реализации создаваемой статической функции.
Например:
class A
{public:
a1(void);
~a1(void);
int Fx1(int i1);
int Fx2(int i2);
protected:
static int Fstat1(void); 
// Статическая функция доступна
//только для статических методов - членов
//данного класса и наследуемых классов
public:
static int Fstat2(void);   
// Общедоступная статическая функция
};

int main(int argc, char* argv[]){
std::cout<<a1::Fstat2();  
// Вызов статической функции
}

Реализация статической функции записывается так же, как и реализация любого другого метода - члена класса. При этом ключевое слово static не указывается.
Например:
int A::FStat1(void) { return 0; }

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

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

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

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

Вызван B::VirtMetod1
Вызван B::VirtMetod1
Вызван A::Metod2
Вызван B::Metod2

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

=0.

Например:

virtual void F1( int) =0;

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

class A{
public:
    A();
    A (const A&);
    virtual A* virt_object1 () {
       return new A();
   }
    virtual A* virt_object2 () {
       return new A(*this);
   }
}
 

Виртуальные классы

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

class A : virtual public B  {   }

Абстрактные классы

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

http://localhost:3232/img/empty.gifШаблоны методов

Шаблоны методов позволяют описывать одинаковую реализацию для различных типов параметров.
Шаблон метода позволяет описать одну реализацию метода для всех допустимых значений параметров. Фактически шаблон метода заменяет набор перегружаемых методов с различными типами параметров.
Шаблон метода - это еще одно проявление полиморфизма языка С++.
Шаблоны методов используют в качестве параметра тип переменной.
В момент компиляции при вызове метода, не имеющего прототипа, выполняется поиск шаблона метода, из которого вызываемый метод может быть сгенерирован.
Шаблон метода указывается ключевым словом template, за которым в угловых скобках указывается список типов, используемых для параметров функции и типа возвращаемого значения.
Например:
template <class T1>
T1 Fx (T1 x, T1 y) {return x+y;}
При использовании шаблона компилятор заменит для вызываемого метода тип шаблона на тип, указанный при вызове метода (T1 на int в следующем примере).
Например:
int i1=1;
int i2=2;
std::cout<<Fx(i1,i2);
Шаблоны классов
Шаблоны классов позволяют определить параметризированный тип.
Шаблоны классов аналогично шаблонам функций позволяют на этапе компиляции создавать определения классов.
Шаблон класса указывается ключевым словом template, за которым в угловых скобках указывается список типов для создания параметризированного класса. Имя шаблона класса указывается после ключевого слова class.
Для создания объекта на основе шаблона класса после имени шаблона в угловых скобках указывается конкретный тип:
имя_шаблона_класса <тип> имя_объекта.
Например:
Пример 12.2. Создание объекта на основе шаблона класса
Работа с памятью
Свободная память, которую можно заказывать в процессе выполнения программы, называется динамической памятью. Для выделения непрерывного блока памяти можно использовать функцию malloc(), а для освобождения - функцию free(). Прототипы этих функций расположены в заголовочном файле stdlib.h.
Например:
int *pIntBuffer;
// Выделение памяти под 5 переменных типа int
pIntBuffer=malloc(5*sizeof(int));
При отсутствии требуемого количества памяти функция malloc возвращает значение null.
Выделение динамической памяти также можно выполнять оператором new, а освобождение - оператором delete. Оператор new автоматически учитывает тип объекта и выделяет требуемое количество памяти.
Пример:
double *pBuffer;
// Выделение памяти под 10 переменных типа double
pBuffer=new double [10];
http://localhost:3232/img/empty.gif

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика