vec;, yoki bitta identifikator uchun Deklaratsiyausing std::string ( ) yoki nomlar maydonidagi barcha identifikatorlar uchun foydalanish direktivasiusing namespace std; ( ). Sarlavha fayllaridagi kod har doim to’liq nom maydoni nomidan foydalanishi kerak.
Quyidagi misol nom maydoni deklaratsiyasini va nomlar maydonidan tashqaridagi kod ularning a’zolariga kirishining uchta usulini ko’rsatadi.
Namespace ContosoData
{
Class ObjectManager
{
Public:
Void DoSomething() {}
};
Void Func(ObjectManager) {}
}
To’liq malakali nomdan foydalaning:
ContosoData::ObjectManager mgr;
Mgr.DoSomething();
ContosoData::Func(mgr);
Bitta identifikatorni qamrab olish uchun foydalanish deklaratsiyasidan foydalaning:
Using ContosoData::ObjectManager;
ObjectManager mgr;
Mgr.DoSomething();
Nomlar maydonidagi hamma narsani qamrab olish uchun foydalanish direktivasidan foydalaning:
Using namespace ContosoData;
ObjectManager mgr;
Mgr.DoSomething();
Func(mgr);
Direktivalardan foydalanish
usingDirektiv a dagi barcha nomlarni aniq kvalifikatsiya sifatida nom maydoni-nomisiznamespace ishlatishga imkon beradi. Agar nomlar sohasida bir nechta turli identifikatorlardan foydalanayotgan bo’lsangiz, amalga oshirish faylida (ya’ni *.cpp) foydalanish direktivasidan foydalaning; agar siz faqat bitta yoki ikkita identifikatordan foydalanayotgan bo’lsangiz, unda nomlar maydonidagi barcha identifikatorlarni emas, balki faqat o’sha identifikatorlarni qamrab olish uchun foydalanish deklaratsiyasini ko’rib chiqing. Agar mahalliy o’zgaruvchi nom maydoni o’zgaruvchisi bilan bir xil nomga ega bo’lsa, nom maydoni o’zgaruvchisi yashirin bo’ladi. Global o’zgaruvchi bilan bir xil nomga ega nom maydoni o’zgaruvchisiga ega bo’lish xatodir.
Nomlar va nomlar maydoni a’zolarini e’lon qilish
Odatda, siz nomlar maydonini sarlavha faylida e’lon qilasiz. Funktsiyangizning ilovalari alohida faylda bo’lsa, ushbu misoldagi kabi funksiya nomlarini kvalifikatsiya qiling.
//contosoData.h
#pragma once
Namespace ContosoDataServer
{
Void Foo();
Int Bar();
}
Contosodata.cpp funksiyasini amalga oshirish, hatto usingfaylning yuqori qismiga direktivani joylashtirgan bo’lsangiz ham, to’liq nomdan foydalanishi kerak:
#include “contosodata.h”
Using namespace ContosoDataServer;
Void ContosoDataServer::Foo() // use fully-qualified name here
{
// no qualification needed for Bar()
Bar();
}
Int ContosoDataServer::Bar(){return 0;}
Nom maydoni bitta faylda bir nechta bloklarda va bir nechta fayllarda e’lon qilinishi mumkin. Kompilyator dastlabki ishlov berish jarayonida qismlarni birlashtiradi va natijada olingan nomlar maydoni barcha qismlarda e’lon qilingan barcha a’zolarni o’z ichiga oladi. Bunga standart kutubxonadagi sarlavha fayllarining har birida e’lon qilingan std nom maydoni misol bo’la oladi.
Nomlangan nom maydonining a’zolari ular e’lon qilingan nom maydonidan tashqarida aniqlanayotgan nomning aniq kvalifikatsiyasi orqali aniqlanishi mumkin. Biroq, ta’rif deklaratsiyaning nom maydonini o’z ichiga olgan nom maydonida e’lon nuqtasidan keyin paydo bo’lishi kerak. Masalan:
// defining_namespace_members.cpp
// C2039 expected
Namespace V {
Void f();
}
Void V::f() { } // ok
Void V::g() { } // C2039, g() is not yet a member of V
Namespace V {
Void g();
}
Ushbu xato nomlar maydoni a’zolari bir nechta sarlavhali fayllarda e’lon qilinganida yuzaga kelishi mumkin va siz ushbu sarlavhalarni to’g’ri tartibda kiritmagansiz.
Global nomlar maydoni
Agar identifikator aniq nomlar maydonida e’lon qilinmagan bo’lsa, u yashirin global nomlar maydonining bir qismidir. Umuman olganda, global nomlar maydonida bo’lishi kerak bo’lgan kirish nuqtasi asosiy Funktsiyadan tashqari, iloji bo’lsa, global miqyosda deklaratsiyalar qilishdan qochishga harakat qiling . Global identifikatorni aniq kvalifikatsiya qilish uchun dagi kabi nomsiz doirani aniqlash operatoridan foydalaning ::SomeFunction(x);. Bu identifikatorni boshqa nomlar maydonidagi bir xil nomli har qanday narsadan ajratib turadi va bu sizning kodingizni boshqalarga tushunishini osonlashtirishga yordam beradi.
Std nom maydoni
Barcha C++ standart kutubxona turlari va funktsiyalari stdnomlar maydonida yoki ichkariga joylashtirilgan nomlar bo’shliqlarida e’lon qilinadi std.
Ichki nom maydonlari
Nomlar bo’shliqlari o’rnatilgan bo’lishi mumkin. Quyidagi misolda ko’rsatilganidek, oddiy ichki o’rnatilgan nom maydoni o’zining ota-ona a’zolariga malakasiz kirish huquqiga ega, lekin ota-ona a’zolari ichki o’rnatilgan nomlar maydoniga (agar u inline sifatida e’lon qilinmasa) malakasiz kirish huquqiga ega emas:
Namespace ContosoDataServer
{
Void Foo();
Namespace Details
{
Int CountImpl;
Void Ban() { return Foo(); }
}
Int Bar(){...};
Int Baz(int i) { return Details::CountImpl; }
}
Oddiy ichki o’rnatilgan nomlar bo’shliqlari ota-ona nomlar maydonining umumiy interfeysining bir qismi bo’lmagan ichki amalga oshirish tafsilotlarini qamrab olish uchun ishlatilishi mumkin.
Inline nom maydonlari (C++ 11)
Oddiy ichki nom maydonidan farqli o’laroq, ichki nomlar maydoni a’zolari ota-ona nom maydonining a’zolari sifatida ko’rib chiqiladi. Bu xususiyat haddan tashqari yuklangan funksiyalarni argumentga bog‘liq holda qidirishni ota-ona va ichki o‘rnatilgan nom maydonida ortiqcha yuklangan funksiyalar ustida ishlash imkonini beradi. Shuningdek, u inline nom maydonida e’lon qilingan shablon uchun ota-ona nom maydonida ixtisoslashuvni e’lon qilish imkonini beradi. Quyidagi misol tashqi kodning sukut bo’yicha ichki nom maydoniga qanday bog’lanishini ko’rsatadi:
//Header.h
#include
Namespace Test
{
Namespace old_ns
{
Std::string Func() { return std::string(“Hello from old”); }
}
Inline namespace new_ns
{
Std::string Func() { return std::string(“Hello from new”); }
}
}
#include “header.h”
#include
#include
Int main()
{
Using namespace Test;
Using namespace std;
String s = Func();
Std::cout << s << std::endl; // “Hello from new”
Return 0;
}
Quyidagi misol ichki nom maydonida e’lon qilingan shablonning ota-onasida ixtisoslikni qanday e’lon qilishingiz mumkinligini ko’rsatadi:
Namespace Parent
{
Inline namespace new_ns
{
Template
Struct C
{
T member;
};
}
Template<>
Class C {};
}
Kutubxonaning umumiy interfeysidagi o’zgarishlarni boshqarish uchun versiya mexanizmi sifatida inline nom maydonlaridan foydalanishingiz mumkin. Masalan, siz bitta ota-ona nom maydonini yaratishingiz va interfeysning har bir versiyasini ota-ona ichiga joylashtirilgan o’z nom maydoniga joylashtirishingiz mumkin. Eng so’nggi yoki afzal qilingan versiyani o’z ichiga olgan nom maydoni inline sifatida tasniflanadi va shuning uchun u ota-ona nom maydonining bevosita a’zosi kabi ko’rsatiladi. Parent::Classni chaqiruvchi mijoz kodi avtomatik ravishda yangi kodga ulanadi. Eski versiyadan foydalanishni ma’qul ko’rgan mijozlar ushbu kodga ega bo’lgan ichki nomlar maydoniga to’liq malakali yo’ldan foydalangan holda unga kirishlari mumkin.
Inline kalit so’zi kompilyatsiya birligidagi nomlar maydonining birinchi deklaratsiyasiga qo’llanilishi kerak.
Quyidagi misol interfeysning ikkita versiyasini ko’rsatadi, ularning har biri ichki nomlar maydonida. Nomlar maydoni interfeysdan v_20ba’zi o’zgarishlarga ega v_10va inline sifatida belgilangan. Yangi kutubxona va qo’ng’iroqlardan foydalanadigan mijoz kodi Contoso::Funcs::Addv_20 versiyasini ishga tushiradi. Qo’ng’iroq qilishga urinayotgan kod Contoso::Funcs::Divideendi kompilyatsiya vaqtida xatolikni oladi. Agar ularga haqiqatan ham ushbu funktsiya kerak bo’lsa, ular v_10aniq qo’ng’iroq qilish orqali versiyaga kirishlari mumkin Contoso::v_10::Funcs::Divide.
Namespace Contoso
{
Namespace v_10
{
Template
Class Funcs
{
Public:
Funcs(void);
T Add(T a, T b);
T Subtract(T a, T b);
T Multiply(T a, T b);
T Divide(T a, T b);
};
}
Inline namespace v_20
{
Template
Class Funcs
{
Public:
Funcs(void);
T Add(T a, T b);
T Subtract(T a, T b);
T Multiply(T a, T b);
Std::vector Log(double);
T Accumulate(std::vector nums);
};
}
}
Nomlar maydoni taxalluslari
Nomlar maydoni nomlari noyob bo’lishi kerak, ya’ni ular ko’pincha juda qisqa bo’lmasligi kerak. Agar ismning uzunligi kodni o’qishni qiyinlashtirsa yoki direktivalardan foydalanish mumkin bo’lmagan sarlavha fayliga yozish zerikarli bo’lsa, siz haqiqiy ismning qisqartmasi bo’lib xizmat qiladigan nomlar maydoniga taxallus yaratishingiz mumkin. Masalan:
Namespace a_very_long_namespace_name { class Foo {}; }
Namespace AVLNN = a_very_long_namespace_name;
Void Bar(AVLNN::Foo foo){ }
Anonim yoki nomsiz fazolar
Siz aniq nom maydoni yaratishingiz mumkin, lekin unga nom bermaysiz:
Namespace
{
Int MyFunc(){}
}
Bu nomsiz yoki anonim nom maydoni deb ataladi va siz o’zgaruvchilar deklaratsiyasini boshqa fayllardagi kodga ko’rinmas holga keltirmoqchi bo’lsangiz (ya’ni, ularga ichki bog’lanishni) nomli nomlar maydoni yaratmasdan foydali bo’ladi. Xuddi shu fayldagi barcha kod identifikatorlarni nomsiz nomlar maydonida ko’rishi mumkin, ammo identifikatorlar nom maydonining o’zi bilan birga ushbu fayldan tashqarida, aniqrog’i tarjima birligidan tashqarida ko’rinmaydi.
Do'stlaringiz bilan baham: