Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция_05_INLINE_STATIC_CONST.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
123.39 Кб
Скачать

Константные функции-члены класса

Функция-член класса также может быть объявлена с модификатором const, который следует за списком параметров. Такая функция не может изменять значение данных-членов класса и не может вызывать не константные функции-члены класса.

Пример 9.

class Coord // базовый класс координат

{

double x, y;

public:

Coord() {x=0; y=0;}

double GetX() const {return x;} // константная функция

double GetY() const {return y;} // константная функция

void GetVal(double X, double Y) const; // константная функция

void SetX(double X) {x=X;}

void SetY(double Y) {y=Y;}

};

Константные объекты

Можно также создавать константные объекты. Для этого их объявления предваряют модификатором const. Например,

const Coord A(3, 5);

Ключевое слово const информирует компилятор, что состояние данного объекта не должно изменяться. В связи с этим компилятор генерирует сообщение об ошибке, если для константного объекта вызывается функция-член (которая может изменить его данные-члены, изменив тем самым его состояние). Исключением из этого правила являются константные функции-члены, которые в силу своего определения не изменяют состояние объекта.

Пример 10.

class Coord // базовый класс координат

{

int x, y;

public:

Coord(int X, int Y) {x=X; y=Y;}

void SetVal(int X, int Y) {x=X; y=Y;}

void GetVal(double &X, double &Y) const; // константная функция

};

Coord::GetVal(double &X, double &Y) const

{

X=x; Y=y;

}

int main()

{

Coord p(3, 8);

const Coord p1(6, 9); // константный объект

int a, b;

cin>>a>>b;

p.GetVal(a, b);

p1.SetVal(a, b); // Ошибка!!! Вызов неконстантной функции-члена

p1.GetVal(a, b);

}

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

mutable <тип_данных> <имя_переменной-члена>;

Пример 11.

class AnyClass

{

mutable int count;

mutable const int *iptr;

public:

int func(int i=0) const

{

count=i++;

iptr=&i;

cout<<iptr;

return count;

}

};

Здесь в операторе mutable const int *iptr; модификатор mutable допустим, так как iptr является указателем на целое число, которое есть константа, хотя сам указатель константой не является.

Использование указателей на функции-члены класса

Можно определить указатель на функцию-член класса. Синтаксис определения следующий:

<возвр_тип> (<имя_класса>::*<имя_указателя>) (< параметры>);

Например:

void (T::*funcPtr) (int x, int у);

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

Например: this->*funcPtr(x, y);

или

*this.*funcPtr(x, y);

Указателю на функцию-член класса передается скрытый указатель this (иначе ему нельзя было бы присвоить значение адреса некоторой функции-члена класса).

Следующий пример демонстрирует использование указателей на функцию-член.

class T

{

int a;

public:

T(int A): a(A){}

void MembFunc() {printf("Hello!");}

void CallMembFunc(void (T::*funcPtr)())

{

this->*funcPtr();

}

};

int main()

{

void (T::*funcPtr)()=&T::MembFunc;

T ob(2000);

ob.CallMembFunc(funcPtr);

}

C++ накладывает определенные ограничения на использование указателей на функции-члены класса:

  • указатель на функцию-член класса не может ссылаться на статическую функцию-член класса (так как ей не передается указатель this);

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