Энергетика


 Дәріс №14. Динамикалық идентификация және типтерді келтіру



Pdf көрінісі
бет20/23
Дата07.02.2022
өлшемі1,03 Mb.
#91462
түріПрограмма
1   ...   15   16   17   18   19   20   21   22   23
Байланысты:
is 1

14 Дәріс №14. Динамикалық идентификация және типтерді келтіру 
Дәрістің мақсаты:
динамикалық идентификация және типтерді келтіру
түсініктерін беру. 
Дәрістің мазмұны:
const_cast, static _cаst, dynamic_cast, reinterpret_cаst
операциялары. 
Полиморфизмді қолдайтын тілдерде компиляция кезінде объекттің типі 
белгісіз болу жағдайлары мүмкін, себебі бағдарламаның орындалуына дейін 
объекттің нақты табиғаты анықталмаған. С++ -те полиморфизм кластар 
иерархиясы, виртуалды функциялар мен базалық класс көрсеткіштері арқылы 
жүзеге асырылады. Осындай байланыс кезінде базалық класс көрсеткіші, 
базалық класс объектісіне сілтеуге немесе осы базалық кластан туылған кез 
келген туынды объектісіне сілтеу үшін қолданылады. Әрбір уақыт мезетінде, 
базалық класс көрсеткіші сілтеме жасай алатын объект типін алдын ала 
анықтау мүмкіндігі бола бермейді. Мұндай жағдайларда объект типін анықтау 
бағдарлама орындалуы кезінде орындалуы керек, ал ол үшін типтің 
динамикалық идентификациясының механизмі қызмет етеді. 
Объекттің типі туралы ақпаратты typeid (объект) операторы арқылы 
алады, ол объекттің объектті типін сипаттайтын type-info тип объектіге 
сілтеме қайтарады. type-info класында келесі ашық мүшелер анықталған: 
Bool operator == (const type_info& объект); // типтерді салыстыру 
Bool operator! = (const type_info& объект); // типтерді салыстыру 
Bool before (const type_info& объект);
Const char*name ( ); // объект атына нұсқауыш 
typeid операторы түрлі объект типтерін алуға мүмкіндік беруіне 
қарамастан, егер оның аргументі ретінде полиморфты базалық кластың 
көрсеткіші берілсе, онда ол анағұрлым пайдалы болады. Мұндай жағдайда, 
оператор автоматты түрде, көрсеткіш сілтеме жасайтын нақты объект типін 
қайтарады. Сөйтіп, typeid операторы көмегімен, программаманың 
орындалуы кезінде, базалық класс нұсқауыш сілтеме жасайтын объект типін 
анықтауға болады. Сонымен қатар бұл сілтемелерге де қатысты болып 
табылады. Егер typeid операторының аргументі ретінде, полиморфты класс 
объектісіне сілтеме берілсе, онда оператор, сілтемесі бар объекттің нақты 
типін қайтарады. typeid операторын полиморфты емес класқа қолданғанда, 
базалық типтің нұсқауышын немесе сілтемесін алады. 
Типтің динамикалық идентификациясы әрқашан қолдана берілмейді, 
бірақ мәндердің полиморфты типтерімен жұмыс істегенде, ол әртүрлі 
жағдайларда өңделетін объектілер типтерін анықтауға мүмкіндік береді. 
// typeid операторын қолдану мысалы:
# include 


54 
# include 
class Base
{ vertual void f ( ) { }; // класты полиморфты етеміз 
}; 
сlass Der1 : public Base{…}; 
class Der2 : public Base {…}; 
int main(void) 
{ int i; 
Base *p,baseob; Der1 d1; Der2 d2; 
cout «″ \n і айнымалыcының типі -бұл ″ « tepeid (i). name( ) « endl; 
// полиморфты типтерді өңдеу
p=& baseob; 
cout «″ р көрсеткіші тип объектісіне сілтеме жасайды ″; 
cout «typeid (*p ) name ( ) «endl; 
p=&d1; 
cout «″р көрсеткіші тип объектісіне сілтеме жасайды ″«typeid (*p ) name
( ); 
p=&d2; 
cout «″\n р көрсеткіші тип объектісіне сілтеме жасайды ″ «typeid (*p )
name (); 
return 0 ; 

Бағдарлама экранға келесі ақпаратты шығарады: 
і айнымалысының типі - int
р нұсқауышы Base типті объектіге сілтеме жасайды 
р нұсқауышы Der1 типті объектіге сілтеме жасайды ″; 
р нұсқауышы Der2 типті объектіге сілтеме жасайды ″; 
Объекттер функцияларға сілтеме бойынша берілетін жағдайда typeid 
операторының нақты қасиеті объекттің нақты типін қайтарады, мысалы: 
oid func ( Base & ref) 
{ cout «″ ref –сілтеме объектіге мына түрдегі «typeid (ret ). name ( ) ;} 
d1, 
d2 объектілері үшін шақыру кезінде олардың дұрыс 
идентификациясы орындалады:
func (d1) және func (d2 ) сәйкесінше. 
typeid операторының басты артықшылығы компиляция кезінде 
белгісіз объекттер типтерін идентификациялау мүмкіндігі болып табылады. 


55 
Экранда түрлі геометриялық фигураларды салу үшін арналған кластар 
иерархиясы анықтайтын бағдарлама мысалын қарастырайық. Иерархия 
басында төрт класты мұрагерленетін Shape абстрактты класы орналасқан: 
Line, Square, Rectangle және NullShape. Функция generator( ) объектіні 
туғызады және оған көрсеткішті қайтарады. Онда қандай объект 
құрылатынын, және rand ( ) - кездейсоқ сандық генераторы анықтайды. main 
( ) функциясында, NullShape типті объекттерден басқа, экранда түрлі типті 
туындалған объектілер қортындысы жүзеге асырылған. Объекттер кездейсоқ 
туатындықтан, алдын ала, келесі қандай объект құрылатыны белгілі 
болмайды. Нәтижесінде, құрылатын объектінің типін анықтау үшін типтің 
динамикалық идентификациясы талап етіледі. 
# include 
# include 
# include 
class Shape 
{ public : virtual void example( )=0;}; 
class Rectangle:public Shape 
{public:void example( ){cout«″ Тікбұрыш\n″;} }; 
class Triangle :public Shape
{ public:void example ( ) { cout«″ \n Үшбұрыш \n ″;} }; 
class line : public Shape 
{ public: void example( ) {cout «″\n Сызық\n″; } }; 
class NullShape 
{ public :void example( ){ } }; 
// Shape класынан туындылар фабрикасы
Shape *generator ( ) 
{ switch (rand ( ) %4) 
{ case о: return new Line ; case 1: return new Rectangle; 
case 2:return new Triangle; case3:return new NullShape; 

return Null; 
} int main (void) 
{ int i; Shape *p; 
for (i=0;i <10;i++) 
{ p=generator( ); // келесі объектіні құру
cout «typeid (*p ) name «endl
// объектіні салады, егер ол NullShape типті емес болса 
if (typeid (*p )! =typeid (NullShape)) p--example( ); 
} return 0; 

Typeid операторы үлгі-кластармен жұмыс істей алады. С++ тілінде 
жазылған бағдарламаны орындағанда типтер түрлері орындалады: нақты 


56 
және нақты емес. Типтердің нақты түрленулері әрқашан программист 
қалауымен орындалады және ол үшін С++ тілінде мыналар бар: 
-
Си тілінен мұрагерленген типті келтіру операциясы;
-
С++ тіліне енгізілген функционалды жазба формасы;
-
const_ cast, dynamic_cast, reinterpret_cast және static_cast 
операциялары.
Соңғы операциялар типтердің түрленулерінің анағұрлым сенімді 
операциялары болып табылады, және оларды барлық қажет жағдайларда 
қолданған жөн. 
const_cast операциясы. 
Берілген операция const модификаторының 
әрекеттерін нөлге айналдыру үшін қолданылады: 
const int i; 
int *p=const_cast(&i); // жай көрсеткішті аламыз 
Жалпы жағдайда бұл операция келесі форматқа ие болады:
const_cast  (V), 
Мұндағы Т типі V типі (бұл әдетегі көрсеткіш) сияқты болу керек. 
Операция Т типті нәтижені қайтарады. Бұл операцияның қажеттілігі 
функцияны жобалағанда const сияқты өзгермейтін параметрлерді сипаттау 
міндетті емес болумен шатастырылған, бірақ мұны жасау ұсынылады. С++ 
ережелері консттантты көрсеткішті жай көрсеткіш орнына беруге рұқсат 
етпейді. Сондықтан const_cast операциясы осы шектеуді айналып өту үшін 
енгізілген. Әрине, мұндай жағдайда функция берілетін көрсеткіш сілтеме 
жасайтын мәнді өзгертпеу керек. 
Компиляция кезінде ( тақырып, ортаға жаз) типтердің түрленуі (static 
_cаst операциясы ) static _cаst операциясы компиляторымен орындалады 
және онсыз жұмыс істеуге болмайтын кезде ғана қолданылады. static_cаst 
операциясын қолданудың мысалын көрсеткіштің қажет типіне void* 
көрсеткішін түрлендіру деп атауға болады, бүтін типін есептеп шығу типіне 
келтіру және туыс типтердің басқа да түрленуі деп те атауға болады. 
Программаны орындау кезіндегі типтердің түрленуі (dynamic_cast) 
dynamic_ cast операциясы әдетте полиморфты объектілер үшін және 
виртуалды базалық кластардың түрленуін төмендету үшін қолданады. Бұл 
кезде, операция программаны орындау кезінде типтерді идентификациялау 
(Run-Time Type Information, RTTI) механизмін қолданады.
Бақылау сұрақтары: 
1)
typeid операторы көмегімен орындауға болатын опрацияларды 
сипаттаңыз. 
2)
Қандай объекттің типін typeid операторымен анықтайды? 
3)
const_cast типті түрлендіру операциясы не үшін керек? 


57 
4)
dynamic_ cast типіті түрлендіру операциясы не үшін керек? 
5)
static _cаst және reinterpret_cаst операциялары не үшін керек? 


Достарыңызбен бөлісу:
1   ...   15   16   17   18   19   20   21   22   23




©engime.org 2024
әкімшілігінің қараңыз

    Басты бет