Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Функции-элементы, дружественные функции, константные функции




 

Поля данных, исходя из принципа скрытия данных, всегда должны быть за­щищены от несанкционированного доступа. Доступ к ним, как правило, должен осуществляться только через функции, включающие методы чтения и записи по­лей. В этих функциях должна осуществляться проверка данных, чтобы не запи­сать случайно в поля неверные данные или чтобы не допустить их неверной трак­товки. Кроме того, функции чтения позволяют не переписывать использующую их программу, даже если необходимо изменить что-то в типе, способах хранения и размещения данных в классе.

Поэтому данные всегда целесообразно объявлять в разделе private — закры­том разделе класса. В редких случаях их можно помещать в protected — защи­щенном разделе класса, чтобы возможные потомки данного класса имели к ним доступ.

Приведем пример. Пусть класс имеет следующее объявление:

 

 

class MyClass

{

public:

void SetA(int); // функция записи

int GetA(void); // функция чтения

private:

int FA;

double В, С;

};

Реализация функций записи и чтения может иметь вид:

void MyClass::SetA(int Value){

if (...) // проверка корректности данных

FA = Value;

}

int MyClass::GetA(void) {return FA;}

 

*** для оценки if((Table1OZ->Value<=5)&&(Table1OZ->Value>=0))

 

В данном случае функция чтения просто возвращает значение поля, но в более сложных классах может потребоваться какая-то предварительная обработка дан­ных. Все описания функций-элементов определяемых вне класса содержат ссылку на класс с помощью операции разрешения области действия "::".

В приведенном примере объявление класса содержит только прототипы функ­ций, а их реализация вынесена из описания класса. Для простых функций реали­зация может быть размещена непосредственно в объявлении класса. Например:

class MyClass

{

public:

void SetA(int Value) {FA= Value;}; // функция записи

int GetA(void) {return FA;} // функция чтения

private:

int FA;

double В, С;

};

Функции, описание которых содержится непосредственно в объявлении клас­са, в являются встраиваемыми функциями inline.

Введение описания функций в объявление класса — является плохим стилем про­граммирования: следует избегать смешения открытого интерфейса класса, содер­жащегося в его объявлении, и реализации класса. Если необходимо реализовать встраиваемые функции, то лучше поместить в объявлении класса их прототип со спецификатором inline:

inline void SetA(int); // функция записи

и отдельно дать реализацию функции. При этом в реализации спецификатор inline не указывается.

Объявления классов следует размещать в заголовочном файле модуля (*.h), а реа­лизацию функций — элементов в отдельном файле реализации (*.cpp). При этом в объяв­лении класса должны содержаться только прототипы функций. Это следует из принципа скрытия информации — одного из основных в объектно-ориентирован­ном программировании. Такая организация программы обеспечивает независи­мость всех модулей, использующих заголовочный файл с объявлением класса, от каких-то изменений в реализации функций-элементов класса.

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

friend void IncFA (MyClass *);

то функция IncFA, не являясь элементом данного класса, получает доступ к его за­крытым элементам. Например, функция IncFA может быть описана где-то в про­грамме следующим образом:

void IncFA(MyClass *P) {P->FA++;}

Дружественными могут быть не только функции, но и целые классы. Напри­мер, можно поместить в объявление своего класса оператор

friend Classl;

и все функции-элементы класса Classl получат доступ к закрытым элементам этого класса.

Иногда у программиста может возникнуть необходимость создать объект класса как кон­стантный с помощью спецификатора const. Например:

const Classl MC1(3);

Если при этом класс содержит не только функции чтения, но и записи данных, то реакция на такой оператор, введенный пользователем, зависит от вер­сии и настройки компилятора. Компилятор может выдать сообщение об ошибке и отказаться от компиляции, а может просто выдать предупреждение и проигнори­ровать спецификатор пользователя const. Если класс содержит только функции чтения, то все должно быть нормально. Но компилятор все равно выдаст предупреждение, а может отказать­ся компилировать программу.

Чтобы избежать этого, можно объявить функции чтения как константные. Для этого и в прототипе, и в реализации после закрывающей список параметров круглой скобки надо написать спецификатор const. Например, можно вклю­чить в объявление класса оператор

int GetA(void) const;

а реализацию этой функции оформить как:

int MyClass::GetA(void) const {return FA;}

Тогда замечания компилятора о константных объектах исчезнут.

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

 




Поделиться с друзьями:


Дата добавления: 2014-01-13; Просмотров: 379; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.007 сек.