* Namespace конструкции и нов стил header файлове
Публикувано на 28 ноември 2008 в раздел С/С++.
Namespace е конструкция за езика C++, която представлява разширение на познатите досега класове, а именно - един namespace може да съдържа в себе си набори от класове. По този начин от една страна се получава естествено обединение на обектите, които имат сходна функционалност, а от друга се решава един основен проблем в дизайна на програмите. Представете си, че имате два header файла, които искате да използвате:
#include "header1.h" #include "header2.h"
Нека обаче в тези файлове се съдържат класове с повтарящи се имена:
// header1.h class myClass { ... }; ... // header2.h class myClass { ... }; ...
В такъв случай моментално в нашата програма ще се получи конфликт, понеже ще се опитаме да дефинираме myClass два пъти. Този проблем се решава, като използваме namespace конструкцията:
// header1.h namespace header1 { class myClass { ... }; } // header2.h namespace header2 { class myClass { ... }; }
Когато искаме да използваме така създадените header файлове ние имаме два метода за работа с класовете в тях. Първият начин е да се извикват директно, чрез указване на namespace:
main(){ ... header1::myClass a; header2::myClass *d = new header1::myClass; ... }
Друг начин е да използваме ключовата дума “using” за един от класовете:
main(){ ... using namespace header1; myClass a; // a ще е от класа в header1 header2::myClass *d = new header2::myClass; ... }
Имайте предвид, че ако укажете “using namespace header1″ и “using namespace header2″ отново ще се появи споменатият преди това конфликт. Затова при използване на namespace се препоръчва да се използва операторът “::”. Ако дефинирате namespace, който няма име, то той по подразбиране ще бъде включен чрез ключовата дума “using” от компилаторът.
Интересна и често използвана при писане на библиотеки възможност са вложени namespace:
namespace root { class A{ public: int var1; }; namespace sub { class A{ public: int var2; }; } } int main () { root::A a; a.var1 = 5; root::sub::A b; b.var2 = 6; return 0; }
Най-често използвания и най-популярен namespace е “std”. Принципно “C++ Standards Committee” са пренаписали напълно стандартната библиотека на C++, като са сложили най-често използваните стандартизирани обекти в този namespace.
Друго много важно обновяване на езика е въвеждането на нов стил header файлове. Досега не сме ги разглеждали, понеже целяхме да имаме максимална съвместимост за програми писани на С и стари компилатори. В кода на програмата всъщност няма особена разлика - просто не се добавя “.h” в името на файла при include:
Стар стил: #include "iostream.h" #include "fstream.h" #include "string.h" #include "math.h" #include "stdlib.h" Нов стил: #include <iostream> #include <fstream> #include <string> #include <math> #include <cstdlib>
Въпреки, че имат известни разлики в имплементацията (например fstream.h добавя iostream.h автоматично, а fstream не; string.h използва С-стил низове, а string използва обектни низове; r тн) главната функционалност и най-често използваните функции остават същите. Препоръчително е при писането на програми за нови компилатори да използвате новата конвенция. Нещата, които трябва да запомните са:
1. Никога не “миксирайте”, като вкарвате библиотеки от стар и нов стил едновременно.
2. Ако компилаторът поддържа новите библиотеки, то е добре да използвате тях, тъй като се счита, че функционалността и надеждността при тях е подобрена.
3. Не е изключено в близко бъдеще новите компилатори да не поддържат старите библиотеки.
4. Ако искате да използвате namespace std, то трябва да добавите поне една от новите библиотеки.
По принцип всички функции в новите стандартни библиотеки използват namespace std. Следният пример демонстрира това, като в допълнение показва още една новост за миксиране на глобални и локални променливи с едно и също име:
#include "stdafx.h" #include <iostream> // Глобална променлива int var = 5; void main(){ // Локална променлива int var = 10; // Отпечатваме локалната променлива std::cout << var << std::endl; // Отпечатваме глобалната променлива std::cout << ::var << std::endl; // Добавяме namespace std using namespace std; // Вече може да използваме cout директно cout << "Hello world" << endl; }
Забележете, че ако не сме добавили “using namespace std” при новия стил функции, то програмата няма да разпознае функциите ако не ги извикаме чрез “std::”.
Ако разполагаме с външна библиотека от функции,как могат да се използват.Къде се поместват в дисковото пространство файловете?Изобщо,кой раздел от C++ дава отговор на този въпрос?
Правиш include и името на файла, а после при компилиране добавяш като параметър директорията, в която го има. При g++ това е -I (include) и -L (lib).
Иначе всяка визуална среда има възможност за добавяне на външна библиотека.