C ++

Квалификатори на C ++ и спецификации за клас на съхранение

Квалификатори на C ++ и спецификации за клас на съхранение

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 от друг:

Все още не е заключено дали 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 ”Има клас, наречен поток, от който е създаден екземпляр на обекта thr. Конструкторът за този обект приема препратка към функцията нишка като аргумент. Името на функцията за нишка в тази програма е thread_function ().

Функцията член () член за специалния обект, при използваната му позиция, кара основната нишка да изчака втората нишка да завърши изпълнението си, преди да продължи да се изпълнява, в противен случай основната () функция може да излезе без (втората) нишка да има даде своя резултат.

Външният спецификатор

С прости думи, за декларация паметта не се разпределя за променливата или функцията, докато за дефиниция се разпределя памет. Външната запазена дума позволява глобална променлива или функция да бъдат декларирани в един файл, но дефинирани в друг. Такива файлове се наричат ​​преводни единици за пълното приложение 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. Те засягат продължителността на живота (продължителността), мястото и начина на използване на променливите в дадено приложение.

Как да използвам AutoKey за автоматизиране на Linux игри
AutoKey е програма за автоматизация на настолни компютри за Linux и X11, програмирана в Python 3, GTK и Qt. Използвайки неговата функционалност за скр...
Как да покажа брояч на FPS в игрите на Linux
Linux игрите получиха голям тласък, когато Valve обяви поддръжка на Linux за Steam клиент и техните игри през 2012 г. Оттогава много AAA и независими ...
Как да изтеглите и пуснете Civilization VI на Сид Майер на Linux
Въведение в играта Civilization 6 е модерен поглед върху класическата концепция, въведена в поредицата от игрите Age of Empires. Идеята беше доста про...