Статические элементы-функции

Для работы со статическими элементами данных создаются статические элементы-функции. Их оглавления имеют вид:

static тип_результата имя_функции (параметры).

Параметры – только статические элементы данных.

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

Статическая функция может вызывать только другие статические

функции-элементы данного класса. Не может быть виртуальной. Вызов статической функции имеет вид:

имя_класса :: имя_функции (фактические параметры);

Пример 1 Демонстрирует факт возможности вызова статической функции_элемента даже при отсутствии объектов данного класса.

# include <stdio. h >

class A

{

public:

static void stat_func ( )

{

puts (“ Я существую сама по себе!”);

}

};

void main ( )

{

A : : static_func ( ); //Вызов статической функции.

}

Пример 2 Демонстрирует особенности обработки статических и нестатических элементов данных статическими и нестатическими функциями – членами класса.

#include<stdio.h>

class coord

{

static float x;

float y;

public:

coord(float a):y(a)

{

}

static void f_stat()

{

puts(“Введите х=”);

scanf(“%f”,&x”);

printf(“x=%f\n”,x);

}

void f_non _stat()

{

puts(“Введите х=”);

scanf(“%f”,&x”);

printf(“x=%f y=%f\n”,x,y);

}

}

float coord::x=12.5;//Инициализация х.

void main()

{

coord w(45);// w.x=12.5;w.y=45.

w.f_stat();//Можно, но через this ничего //не передается.

w.f_non_stat();

coord::f_stat();//Еще один способ//вызова статической функции.

}

В этом примере приведен конструктор инициализации. Он может инициализировать только нестатический элемент данных y. Статическая функция-элемент f_stat() обрабатывает статический элемент данных x. При попытке ввода нестатического элемента данных y его значение не изменится. Статическая функция-элемент не обрабатывает нестатические элементы данных. Зато нестатическая функция-элемент f_non_stat() может осуществлять ввод статического элемента данных x. Если при описании класса приведен прототип статической функции – члена, а сама функция определена позже, то ключевое слово static следует ставить только перед прототипом.

Константные объекты и константные элементы- функции

Ранее были рассмотрены const элементы-данные. Для их инициализации в конструкторе употреблялся список инициализации. Например:

Class coord

{

Const int x, y;

public:

coord (int a, int b): x(a), y(b)

{

}

};

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

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

Перед константным объектом пишется ключевое слово сonst. Например:

Class A

{

===========

};

Void main ( )

{

const A w; // w -константный объект

}

Константная функция-элемент выглядит так:

Class A

{

===========

public:

Тип_результата имя_функции (параметры) const

{

===========

}

};

Пример.

# include <stdio.h>

Class A

{

Int x, y;

public:

A ( )

{

}

A (int a, int b)

{

x=a;

y=b;

}

//Сейчас будет попытка выполнить недопустимое присвоение в

//константной функции

Void p_const ( ) const

{

x=12; //Cannot modify a const object

y=15; //Cannot modify a const object

}

//Далее эти же действия выполняет неконстантная функция

Void p_non_const ( )

{

x=12;

y=15;

}

};

Void main ( )

{

const A w (1,2); // w -константный объект

A q; // q -неконстантный объект

w.p_const ( ); //Разрешается

q.p_const ( ); //Разрешается

w.p_non_const ( ); //Warning: non-const

// function A::p_non_const ( ) called for

// const object. Это сообщение будет независимо от того

//есть ли недопустимое присвоение в p_non_const ( ) или нет.

}

Внимание! Константная функция не может включать операцию присвоения для элементов-данных. Нельзя присвоить х=12; у=15, как это показано в примере. Но обнаруживается, что компилятор “не замечает”, если в константной функции ввести новые значения элементов-данных для константного объекта. Так, например, в константной функции p_const ( ) можно сделать так:

Void p_const ( ) const

{

puts (“Введите х, в”);

scanf (“%i%i”, &x, &y);

}

Лекция 22

Наследование классов

Нередко несколько классов могут иметь одинаковые элементы данных. Например, class student, class teacher, class officer должны иметь такие элементы-данные, как имя, адрес, возраст. В этом случае удобно сделать т.н. базовый класс class man, у которого будут перечисленные общие для нескольких классов элементы данных, а также необходимые члены-функции. А у этого базового класса будут производные от него классы: class student, class teacher, class officer. Эти классы будут использовать элементы базового класса и, кроме этого, иметь свои собственные элементы данных и элементы-функции.

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

сlass Base

{

.

.

.

};

сlass Derived: ключ_доступа Base

{

.

.

.

};

Ключ_доступа не является обязательным и может быть private, protected или public. Если он не указан, то по умолчанию принимается private для классов и public для структур.

Ключ_доступа определяет уровень доступа к элементам базового класса. Ниже приводится таблица с вариантами доступа.

Ключ_доступа Доступ в базовом классе Доступ в производном классе
public рublic рrotected private рublic рrotected private
protected рublic рrotected private рrotected рrotected private
private рublic рrotected private рrivate рrivate рrivate

В последнем случае имеет место доступ лишь к членам-функциям базового класса (если они в области действия метки доступа рublic).

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

Пример.

сlass А

{

.

.

. };

сlass В

{

..

.

};

сlass С: рublic А, рublic В

{

.

.

};

Здесь класс Сявляется производным от базовых для него классов А и В. Рассмотрим пример простого наследования. Базовый – class man. Производный – сlass student. Напомним, что метка доступа рrotected в базовом классе позволяет иметь доступ из производного класса к элементам базового, находящимся в области действия этой метки.

#include<stdio.h>

class man

{

рrotected:

char* name;//имя

char*address;//адрес

int age;//возраст

рublic:

void get_man_info()

{

name=new char[15];

address=new char[20];

puts(“Введите имя”);

fflush(stdin);

scanf(“%s”,name);

puts(“Введите адрес”);

fflush(stdin);

scanf(“%s”, address );

puts(“Введите возраст”);

scanf(“%i”, &age );

}

void put_man_info()

{

printf(“Имя человека %s.Его адрес % s. Возраст %i\n”,name,address,age);

}

}: //Закончилось описание класса man

class student:public man

{

char* group; //группа

рublic:

void get_stud_info()

{

group =new char[10];

puts(“Введите группу”);

fflush(stdin);

scanf(“%i”, group );

}

void put_stud_info()

{

printf(“Имя студента %s.Его адрес % s. возраст. Учится в группе % s \n”,name,address,age, group);// Используются элементы-данные из базового класса.

}

}

void main

{

man x;//Элемент базового класса

x.get_man_info();

x.put_man_info();

student y; //Элемент производного класса

y.get_man_info();

y.get_stud_info();

y.put_stud_info();

}

Здесь объект производного класса y вызывает функцию get_man_info(), являющуюся членом-функцией базового класса man. При вызове y.put_stud_info() будут выведены y.name, y.address, y.age и y.group.

В принципе, class student мог бы быть базовым, например, для class stud_sport (студент-спортсмен). Для этого в class student метку доступа к элементу данных group нужно сделать рrotected. Тогда объекты класса stud_sport смогут использовать элементы-данные и члены-функции как класса student, так и класса man, являющегося базовым для класса student.

Наши рекомендации