CV означава Constant-Volatile. Декларацията на обект, който не е предшестван от const и / или volatile е cv-неквалифициран тип. От друга страна, декларирането на обект, който е предшестван от const и / или volatile е cv-квалифициран тип. Ако обект е обявен за const, стойността в неговото местоположение не може да бъде променена. Летлива променлива е променлива, чиято стойност е под влиянието на програмиста и следователно не може да бъде променяна от компилатора.Спецификаторите на класовете за съхранение се отнасят до живота, мястото и начина, по който съществува даден тип. Спецификаторите на класове за съхранение са статични, променливи, thread_local и extern.
Тази статия обяснява квалификаторите C ++ и спецификациите на класовете за съхранение. По този начин някои предварителни познания по C ++ са полезни, за да оценим наистина статията.
Съдържание на статията:
- Квалификации
- Спецификатори на класовете за съхранение
- Заключение
Квалификации:
конст
Обект, деклариран като константа, е обект, чието съхранение (местоположение) не може да бъде променено. Например в изявлението:
int const theInt = 5;Стойността 5 в хранилището за theInt не може да бъде променена.
летлив
Обмислете следното твърдение:
int portVal = 26904873;Компилаторите понякога пречат на стойността на променлива с надеждата да оптимизират програмата. Компилаторът може да поддържа стойността на променлива като константа, когато не се предполага, че е постоянна. Стойностите на обекти, които са свързани с картографирани в паметта IO портове или Прекъсване на подпрограми на периферни устройства, могат да бъдат намесени от компилатора. За да предотвратите подобни смущения, направете променливата volatile, като:
int volatile portVal;portVal = 26904873;
или като:
int volatile portVal = 26904873;
Комбиниране на const и volatile:
const и volatile могат да се появят в едно изявление, както следва:
int const volatile portVal = 26904873;cv-квалификации
Променлива, предшествана от const и / или volatile, е cv-квалифициран тип. Променлива, която не е предшествана с const или volatile или и двете, е cv-неквалифициран тип.
Поръчка:
Един тип може да бъде по-квалифициран за cv от друг:
- Никой cv-квалификатор не е по-малък от const квалификатор
- Никой cv-квалификатор също не е по-малко от нестабилен квалификатор
- Никой cv-квалификатор не е по-малък от const-volatile квалификатор
- const квалификаторът е по-малък от const-volatile qualifier
- volatile qualifier е по-малко от const-volatile qualifier
Все още не е заключено дали const и volatile са от един и същ ранг.
Масив и инстанциран обект:
Когато масивът е деклариран за константа, както в следващия оператор, това означава, че стойността на всеки елемент от масива не може да бъде променена:
const char arr [] = 'a', 'b', 'c', 'd';Независимо дали става дума за „a“, „b“, „c“ или „d“, то все още не може да бъде променено на друга стойност (символ).
Подобна ситуация се отнася за екземпляр на обект от клас. Обмислете следната програма:
#includeизползване на пространство от имена std;
клас Кла
публично:
char ch0 = 'a';
char ch1 = 'b';
char ch2 = 'c';
char ch3 = 'd';
;
int main ()
const Cla obj;
връщане 0;
Поради твърдението „const Cla obj;“ с const във функцията main (), нито 'a', нито 'b', нито 'c', нито 'd' могат да бъдат променени на друга стойност.
Спецификации на класа на съхранение:
Спецификаторите на класовете за съхранение са статични, променливи, thread_local и extern.
The статичен спецификатор на клас за съхранение
Спецификаторът на статичен клас за съхранение позволява променливата да живее, след като обхватът й е преминал, но не може да бъде достъпен директно.
Следващата програма илюстрира това с рекурсивна функция:
#includeизползване на пространство от имена std;
int funct ()
статичен int stac = 10;
Cout << stac < 50)
Cout << '\n';
връщане 0;
funct ();
int main ()
funct ();
връщане 0;
Резултатът е:
10 20 30 40 50Ако статичната променлива не е инициализирана при първата си декларация, тя приема стойността по подразбиране за нейния тип.
Статичният спецификатор може да се използва и с членове на клас; използването тук е различно. Тук тя позволява на члена да бъде достъпен без екземпляр за обекта.
Следната програма илюстрира това за член на данни:
#includeизползване на пространство от имена std;
клас Кла
публично:
статичен const int num = 8;
;
int main ()
Cout << Cla::num << '\n';
връщане 0;
Резултатът е:
8Статичният член на данните трябва да бъде постоянен. Имайте предвид, че използването на оператора за разделителна способност за достъп до статичната променлива извън нейния обхват (в основната функция).
Следващата програма илюстрира използването на “static” за функция член:
#includeизползване на пространство от имена std;
клас Кла
публично:
метод на статична празнота ()
Cout << "Of static member function!" << '\n';
;
int main ()
Cla :: method ();
връщане 0;
Резултатът е:
На статична функция член!
Имайте предвид, че използването на оператора за резолюция на обхвата за достъп до функцията за статичен член извън неговия обхват (в основната функция).
Променящият се спецификатор
Не забравяйте, отгоре, че ако екземплярният обект започва с const, стойността на някой от неговите нормални членове на данни не може да бъде променена. И за да може всеки такъв член на данни да бъде променен, той трябва да бъде деклариран, променлив.
Следващата програма илюстрира това:
#includeизползване на пространство от имена std;
клас Кла
публично:
char ch0 = 'a';
char ch1 = 'b';
променлив char ch2 = 'c';
char ch3 = 'd';
;
int main ()
const Cla obj;
обект.ch2 = 'z';
Cout << obj.ch0 << " << obj.ch1 << " << obj.ch2 << " << obj.ch3 << " << '\n';
връщане 0;
Резултатът е:
'a "b" z "d'Локалният спецификатор на thread_local
При нормалното стартиране на програма се изпълнява един кодов сегмент, след това следващият кодов сегмент, последван от друг кодов сегмент след това и т.н. Това е една нишка; основната нишка. Ако два кодови сегмента се изпълняват едновременно (една и съща продължителност), тогава е необходима втора нишка. Резултатът от втората нишка може дори да е готов преди основната нишка.
Функцията main () е като основната нишка. Програмата може да има повече от две нишки за такова асинхронно поведение.
Втората нишка се нуждае от обхват (блок обхват), за да работи. Това обикновено се осигурява от обхвата на функцията, функция. Променлива във външен обхват, която може да се види в обхвата на втората нишка.
Следващата кратка програма илюстрира използването на спецификатора thread_local:
#include#include
използване на пространство от имена std;
thread_local int inter = 1;
void thread_function ()
inter = inter + 1;
Cout << inter << "nd thread\n";
int main ()
конец thr (& thread_function); // thr започва да работи
Cout << inter << "st or main thread\n";
thr.присъединяване(); // основната нишка изчаква нишката, thr да завърши
връщане 0;
Резултатът е:
1-ва или основна нишка2-ра нишка
Променливата inter, предшествана от thread_local, означава, че inter има отделен екземпляр във всяка нишка. И че може да бъде модифициран в различни нишки, за да има различни стойности. В тази програма му се присвоява стойността 1 в основната нишка и се модифицира към стойността 2 във втората нишка.
Нишката се нуждае от специален обект, за да работи. За тази програма библиотеката, включена от „#include
Функцията член () член за специалния обект, при използваната му позиция, кара основната нишка да изчака втората нишка да завърши изпълнението си, преди да продължи да се изпълнява, в противен случай основната () функция може да излезе без (втората) нишка да има даде своя резултат.
Външният спецификатор
С прости думи, за декларация паметта не се разпределя за променливата или функцията, докато за дефиниция се разпределя памет. Външната запазена дума позволява глобална променлива или функция да бъдат декларирани в един файл, но дефинирани в друг. Такива файлове се наричат преводни единици за пълното приложение C ++.
Въведете следната програма и я запазете с името на файла, mainFile:
#includeизползване на пространство от имена std;
int myInt;
const char ch;
void myFn ();
int main ()
myFn ();
връщане 0;
Променливата myInt, константата променлива ch и функцията myFn () са декларирани без да са дефинирани.
Въведете следната програма с дефинициите и я запишете с името на файла, otherFile, в същата директория:
#includeизползване на пространство от имена std;
int myInt = 10;
const char ch = 'c';
void myFn ()
Cout << "myFn() says " << myInt << " and " << ch <<'\n';
Опитайте да компилирате приложението на терминала (командния ред на DOS) със следната команда и забележете, че може да не се компилира:
g ++ основен файл.cpp otherFile.cpp -o завършен.exeСега предшествайте трите декларации в mainFile с думата „extern“, както следва:
extern int myInt;extern const char ch;
extern void myFn ();
Запазете отново mainFile. Компилирайте приложението с:
g ++ основен файл.cpp otherFile.cpp -o завършен.exe(Ето как се компилират отделни файлове за едно и също приложение в C ++)
И трябва да се компилира. Сега стартирайте приложението, завършете.exe, а изходът трябва да бъде:
myFn () казва 10 и cИмайте предвид, че с използването на “extern”, константна променлива може да бъде декларирана в един файл, но дефинирана в друг. Когато се занимавате с декларация за функция и дефиниция в различни файлове, използването на extern е по избор.
Кога да се използва външно? Използвайте го, когато нямате заглавни файлове с глобални декларации.
“Extern” се използва и с декларации на шаблони - вижте по-късно.
Заключение:
Променлива, предшествана от const и / или volatile, е cv-квалифициран тип. Променлива, която не е предшествана с const или volatile или и двете, е cv-неквалифициран тип.
Спецификаторите на класове за съхранение са статични, променливи, thread_local и extern. Те засягат продължителността на живота (продължителността), мястото и начина на използване на променливите в дадено приложение.