Domyślnie używaj funkcji z przestrzenią nazw.
Klasy mają budować obiekty, a nie zastępować przestrzenie nazw.
W kodzie obiektowym
Scott Meyers napisał cały artykuł do swojej książki Effective C ++ na ten temat: „Wolę funkcje nieprzyjazne od innych niż funkcje członkowskie”. Internetowe odniesienie do tej zasady znalazłem w artykule z Herb Sutter:http://www.gotw.ca/gotw/084.htm
Ważne jest, aby wiedzieć, że: W C ++ funkcje w tej samej przestrzeni nazw, w której klasa należy do interfejsu tej klasy (ponieważ ADL przeszuka te funkcje podczas rozwiązywania wywołań funkcji).
Funkcje z przestrzenią nazw, chyba że zostaną uznane za „przyjaciel”, nie mają dostępu do wewnętrznych elementów klasy, podczas gdy metody statyczne mają.
Oznacza to na przykład, że utrzymując klasę, jeśli chcesz zmienić elementy wewnętrzne swojej klasy, będziesz musiał szukać efektów ubocznych we wszystkich jej metodach, w tym statycznych.
Rozszerzenie I
Dodawanie kodu do interfejsu klasy.
W języku C # możesz dodawać metody do klasy, nawet jeśli nie masz do niej dostępu. Ale w C ++ jest to niemożliwe.
Ale nadal w C ++ możesz nadal dodawać funkcje przestrzeni nazw, nawet do klasy, którą ktoś dla ciebie napisał.
Patrz z drugiej strony, jest to ważne przy projektowaniu kodu, ponieważ umieszczając swoje funkcje w przestrzeni nazw, upoważnisz użytkowników do zwiększenia / ukończenia interfejsu klasy.
Rozszerzenie II
Efektem ubocznym poprzedniego punktu jest niemożliwość zadeklarowania metod statycznych w wielu nagłówkach. Każda metoda musi być zadeklarowana w tej samej klasie.
W przypadku przestrzeni nazw funkcje z tej samej przestrzeni nazw można zadeklarować w wielu nagłówkach (prawie standardowa funkcja zamiany jest tego najlepszym przykładem).
Rozszerzenie III
Podstawową zaletą przestrzeni nazw jest to, że w niektórych kodach można uniknąć wspominania o niej, jeśli użyjesz słowa kluczowego „using”:
#include <string>
#include <vector>
// Etc.
{
using namespace std ;
// Now, everything from std is accessible without qualification
string s ; // Ok
vector v ; // Ok
}
string ss ; // COMPILATION ERROR
vector vv ; // COMPILATION ERROR
Możesz nawet ograniczyć „zanieczyszczenie” do jednej klasy:
#include <string>
#include <vector>
{
using std::string ;
string s ; // Ok
vector v ; // COMPILATION ERROR
}
string ss ; // COMPILATION ERROR
vector vv ; // COMPILATION ERROR
Ten „wzorzec” jest obowiązkowy dla właściwego użycia prawie standardowego idiomu zamiany.
Jest to niemożliwe w przypadku metod statycznych w klasach.
Przestrzenie nazw C ++ mają więc własną semantykę.
Ale idzie dalej, ponieważ można łączyć przestrzenie nazw w sposób podobny do dziedziczenia.
Na przykład, jeśli masz przestrzeń nazw A z funkcją AAA, przestrzeń nazw B z funkcją BBB, możesz zadeklarować przestrzeń nazw C i wprowadzić AAA i BBB w tej przestrzeni nazw za pomocą słowa kluczowego.
Wniosek
Przestrzenie nazw dotyczą przestrzeni nazw. Klasy są dla klas.
C ++ został zaprojektowany, więc każda koncepcja jest inna i jest używana w różnych przypadkach, w różnych przypadkach, jako rozwiązanie różnych problemów.
Nie używaj klas, gdy potrzebujesz przestrzeni nazw.
A w twoim przypadku potrzebujesz przestrzeni nazw.