функциите-елементи на класа могат да се предефинират, но само с помощта на други функции-елементи от този клас; типична грешка e
компонентите на функциите-елементи имат област на действие функция – например променливите, които са дефинирани в тялото на функция-елемент са известни само на тази функция;
ако във функция-елемент се дефинира променлива с име, съвпадащо с името на променлива от област на действие клас, то първата скрива втората; такива скрити променливи могат да станат достъпни чрез бинарната операция за разрешаване на област на действие с ляв операнд името на класа и десен операнд името на променливата;
скритите външни променливи могат да станат достъпни с помощта на унарната операция за разрешаване на област на действие;
class Count
{ public:
int x;
void print () { cout << x << endl; }
} ;
void main ()
{ Count counter, *counterPtr = &counter, &counterRef = counter;
counter.x = 7;
counter.print ();
counterRef.x = 8;
counterRef.print ();
counterPtr->x = 10;
counterPtr->print ();
}
спецификаторите за достъп до елемент public, private, protected се използват за управление на достъпа до данните-елементи и функциите-елементи на класа; по премълчаване спецификаторът за достъп е private, т.е. всички елементи след заглавието до първия спецификатор за достъп са закрити;
закритите елементи са достъпни само за функциите-елементи и за приятелските функции на този клас; откритите елементи на класа са достъпни за всички функции в програмата; закритите елементи на класа и описанията на откритите функции-елементи са недостъпни за клиентите на класа; типична грешка е да се прави опит за достъп до закритите елементи на даден клас във функция, която не елемент на този клас или негов приятел;
пример с класа Time:
void main ()
{ Time t;
t.hour = 7;//компилаторът дава грешка
cout << t.minute;//компилаторът дава грешка
}
в дефиницията на класа се препоръчва най-напред да се използва спецификатор за достъп public и след това private; това концентрира вниманието на клиентите на класа върху неговия открит интерфейс;
добър стил на програмиране е използването на закрити данни-елементи и открити функции-елементи за задаване и получаване на стойностите на закритите данни-елементи;
клиент на класа може да бъде функция-елемент на друг клас или външна функция;
структурите в C++ са разширени с възможности за задаване на режим на достъп до елементите и с възможности за включване на функции-елементи; в структурите по премълчаване се приема достъп public; в C++ структурите и класовете са взаимнозаменяеми;
създателите на класове използват режимите на достъп за да осигуряват скриване на информацията и прилагане на принципа за най-малките привилегии;
функциите-елементи или приятелските функции на един клас, които осигуряват достъп до закритите данни-елементи на класа се наричат функции за достъп; например много често се използва функция за достъп с име get, която е за прочитане на стойностите на закритите данни или функция за достъп с име set за задаване и изменение на закрити данни; ако е необходимо тези две функции биха могли да извършват проверка за коректността на данните; те, също така, могат да преобразуват данните от вида, използван в интефейса, във вида, използван при реализацията;
друго типично използване на функциите за достъп е проверката на определено условие – такива функции се наричат предикатни функции; пример за предикатна функция е функцията isEmpty за всеки клас-контейнер, т.е. клас, който може да съдържа много елементи, например свързан списък, стек, опашка; програмата ще използва функцията isEmpty преди да се опита да прочете поредния елемент от обекта на контейнера; предикатната функция isFull би могла да проверява обект от клас-контейнер дали има достатъчно място в него; подобни обслужващи функции не са част от интерфейса и те не са предназначени за използване от клиентите на класа, затова те са закрити функции-елементи и се използват за обслужване на другите функции-елементи на класа;
примерна програма:
#include
#include //за параметризираните манипулатори
class SalesPerson
{ public:
SalesPerson ();
void SetSales (int, double);
void PrintAnnualSales ();
private:
double Sales[12];
double TotalAnnualSales ();
};
SalesPerson::SalesPerson ()
{ for (int i = 0; i < 12; i++)
Sales[i] = 0;
}
void SalesPerson::SetSales ( int month, double amount)
{ if (month>=1 && month <=12 && amount > 0)
Sales [month-1] = amount;
else cout << “Грешка!” << endl;
}
double SalesPerson::TotalAnnualSales ()
{ double total = 0;
for (int i = 0; i < 12; i++)
total += Sales[i];
return total;
}
void SalesPerson::PrintAnnualSales ()
{ cout << setprecision (2)
<< setiosflags (ios::fixed | ios::showpoint)
<< “Сума на продажбите: $“
<< TotalAnnualSales() << endl;
}
void main ()
{ SalesPerson S;
double SalesFigure;
for (int i = 1; i <=12; i++)
{ cout << “Въведете продажби за месец “ << i << “: “;
cin >> SalesFigure;
S.SetSales (i, SalesFigure);
}
S.PrintAnnualSales();
}
използвали сме параметризиран манипулатор:
setprecision (int n)
той изисква включването на заглавния файл iomanip.h; този манипулатор установява точност от n знака след десетичната точка при извеждане на числа с плаваща точка; по премълчаване точността е 6 знака след десетичната точка; при това се извършва закръгляне към най-близкото цяло число;
манипулаторът:
setiosflags (long f)
задава форматни спецификации, определени чрез флага f;
константата ios::fixed води до извеждане на числата с плаваща точка като дробно-десетични; константата ios::showpoint води до извеждане на десетичната точка и нулевите младши разряди; двете константи са свързани с ‘|’ (побитово или), тъй като и двете трябва да се включат във флага f;
Сподели с приятели: