- •Встраиваемые (inline) функции
- •Файл Dot.H
- •Статические данные-члены класса
- •Файл Dot.H
- •Файл Dot.Cpp
- •Файл Main.Cpp
- •В памяти существует 3 объекта типа Dot
- •Статические функции-члены класса
- •Константные функции-члены класса
- •Константные объекты
- •Использование указателей на функции-члены класса
- •Массивы объектов класса
Константные функции-члены класса
Функция-член класса также может быть объявлена с модификатором 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);
указатель на функцию-член класса не может быть преобразован в указатель на обычную функцию, не являющуюся членом какого-нибудь класса (по той же причине).
