* 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).
Иначе всяка визуална среда има възможност за добавяне на външна библиотека.