Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
госы 2 раздел.docx
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
39.8 Кб
Скачать

11.Статические элементы класса.

Спецификатор класса памяти static м.б. использован в объявлении элементов данных и методов.

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

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

class A

{

 static int A;

 static func();

}

b=A::A;

A::func();

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

Пример:

class X

{

 int member;

 static Func(int i, X*ptr);

}

X:: Func(int i, X*ptr);

{

 member = i; неправильно

 ptr -> member=i; правильно

}

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

Главное назначение статических элементов состоит в том, чтобы отслеживать данные, общие для всех объектов класса (число созданных объектов, последний используемый ресурс), уменьшение числа видимых глобальных имен.

12.Виртуальные функции

Виртуальные функции преодолевают сложности решения с пмощью полей типа, позволяя программисту описывать в базовом классе функции, которые можно переопределять в любом проиводном классе. Компилятор и загрузчик обеспечивают правильное соответствие между объектами и применяемыми к ним функциями. Например: struct employee (* employee* next; char* name; short department; // ... virtual void print(); *); Ключевое слово virtual указывает, что могут быть разлиные варианты функции print() для разных производных классов, и что поиск среди них подходящей для каждого вызова print() является задачей компилятора. Тип функции описывается в базвом классе и не может переописываться в производном классе. Виртуальная функция должна быть определена для класса, в ктором она описана впервые. Например: void employee::print() (* cout «„ e-“name „„ „\t“ «« e-“department «« «\n“; // ... *) Виртуальная функция может, таким образом, использоваться даже в том случае, когда нет производных классов от ее класа, и в производном классе, в котором не нужен специальный вариант виртуальной функции, ее задавать не обязательно. Просто при выводе класса соответствующая функция задается в том случае, если она нужна.

13.

14.

15.

16.

17.Шаблоны классов.

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

Понятие шаблона было введено Страуструпом для решения описанной в начале проблемы (необходимость работы с несколькими типами без дублирования кода).

template <class T>

struct Array{

   T& operator [] (size_t i){

       return data_[i];

   }

private:

   T* data_;

   size_t size_;

};

Примечание: вместо class можно писать typename

Компилятор подставит вместо T формальный параметр.

Array<int> m;

Array<double> d;

Без этих строк код шаблона не будет скомпилирован и не попадёт в объектный файл.         Шаблон - это декларация, в нём нет выполняемого кода.

Процесс создания класса называется инстанцированием.

Если ниже создать другой экземпляр с тем же типом:

Array<int> q;

то не возникнет повторения, это будет экземпляр того же самого класса Array<int>, т.о. шаблон - не просто подстановка.

Полное описание шаблона должно быть известно до его использования. Следовательно, нельзя разбить объявление и реализацию на .cpp и .h файлы, вся реализация должна быть известна и находиться в .h файле. Это объясняется тем, что .cpp файлы компилируются отдельно и независимо друг от друга. Это громоздко, однако в пределах одного .h файла можно сначала написать объявление, вынеся описание в конец файла:

//объявление

template <class T>

struct Array{

   T& operator [] (size_t i);

private:

   T* data_;

   size_t size_;

};

 

//определение

template<class T>

T& Array<T>::operator [] (size_t i){

   return data_[i];

}

Из эстетических соображений можно вынести определение в отдельный заголовочный файл (например “array_impl.h”) и подключить его после объявления.

Итог:

+ Шаблоны - конструкции языка, компилятор понимает, что это.

-  Это довольно громоздко, реализация должна быть известна.