itmo.ru aco.ifmo.ru c-visionlab.ru
вернуться в оглавление предыдущая глава предыдущий параграф следующий параграф следующая глава


4.4. Модификаторы, селекторы и другие члены классов

4.4.1. Модификаторы и селекторы

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

Модификаторы позволяют установить значение private переменной-члена. Обычно имя модификатора состоит из Set_ и имени переменной-члена.

// установка показателя преломления 
void Set_n(double n); 
// установка осевого расстояния 
void Set_d(double d); 

Селекторы позволяют узнать значение private переменной-члена.

// получение показателя преломления 
double Get_n() const; 
// получение осевого расстояния 
double Get_d() const; 

// вызов модификатора:
lens5.Set_n(1.6); 
// вызов селектора:
cout<<lens5.Get_n()<<endl; 

4.4.2. Ключевые слова const и inline

Обратите внимание, что функции-селекторы обычно являются константными. При описании и реализации функции после перечисления параметров указывается ключевое слово const, что означает, что данная функция гарантированно не изменяет значение переменных-членов класса. Другие функции (не селектор), которые не изменяют значения переменных-членов, тоже указываются как константные. Например, вывод значений параметров на экран, или вычисления, которые не меняют значения переменных-членов:

double Get_n() const; 
void write(std::ostream& out) const;

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

/////////////////////////////////////////////////////////////////////////////
// установка показателя преломления 
inline void Lens::Set_n(double n)
{
    m_n=n; 
    CalculateParaxial();
} 
/////////////////////////////////////////////////////////////////////////////
// получение показателя преломления
inline double Lens::Get_n() const
{
    return m_n; 
} 
/////////////////////////////////////////////////////////////////////////////

4.4.3. Функции-утилиты

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

Можно было бы организовать эту функцию по-другому – не хранить в линзе значения ее параксиальных характеристик, и не перевычислять их в каждом модификаторе, а вычислять параксиальные характеристики один раз, и возвращать прямо в функции CalculateParaxial. В этом случае функция CalculateParaxial должна быть public.

4.4.4. Сохраняемость

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

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

/////////////////////////////////////////////////////////////////////////////
// запись
void Lens::write(ostream& out) const
{
    out<<m_r1<<" "<<m_r2<<" "<<m_d<<" "<<m_D<<" "<<m_n<<endl;
} 
/////////////////////////////////////////////////////////////////////////////
// чтение
void Lens::read(istream& in)
{
    in>>m_r1>>m_r2>>m_d>>m_D>>m_n;
    CalculateParaxial();
} 
/////////////////////////////////////////////////////////////////////////////