Globalna przestrzeń nazw a zmienne globalne

0

Witam

Mam problem ze zrozumieniem dyrektywy using w języku C++

namespace Jill
{
	double fetch = 2;
}

using namespace Jill;
double fetch;

int main(void)
{
	using namespace std;
	//cout << Jill::fetch;
	cout << ::fetch;
        return 0;
}

Dlaczego kompilator nie generuje tutaj blędu? fetch z przestrzeni nazw jest importowane do przestrzeni globalnej nazw czyli wydaje mi sie ze to jest cos takiego jakby miał dwie takie same deklaracje, jedna pod drugą,czyli jest to błąd:

double fetch = 2;
double fetch;

W książce S.Prata "Język C++ Szkoła porgramowania" jest podana takie zdanie na temat dyrektywy using ktorego nie rozumiem, mogłby ktoś mi je objaśnić?
Oto zdanie:
"[...] w zastosowaniu dyrektywy using rozstrzyganie nazw odbywa się tak, jakby nazwy te zostały zadeklarowane w najmniejszym możliwym obszarze deklaracyjnym zawierającym zarówno przestrzeń nazw, jak i dyrektywę using."

0

To chyba jest tak jak z "przysłanianiem metod w klasie".
Tutaj nie ma błędu bo zasłoniłeś zmienną z namespace, zmienną globalną.
Gdybyś miał dwa pliki i w obu zadeklarował byś taką samą zmienną globalną to wtedy dostałbyś błąd.
Tutaj go nie ma bo jedna jest w twoi globalnym pudełku, a druga w pudełku Jill::fetch

0

Ale dyrektywa using nie powoduje ze to pudełko sie otwiera? I zmienna z przestrzeni nazw staje sie globalną zmienną tak jak druga zmienna fecht zadeklarowana poza przestrzenią nazw. Wychodzi z tego ze obie zmienne sa globalne I sie nie przysłaniają a skoro maja takie same nazwy to powinien być konflikt.

0

Nie, pudełko się nie otwiera. :) Wciąż masz tylko jedną zmienną globalną, a drugą w przestrzeni nazw. I ta druga nigdy globalna się nie stanie. Jest tylko do niej uproszczony dostęp... BTW, to też działa:

#include <iostream>

using namespace std;

int cout = 15;

int main() {
    int cout = 10;
}
0

"[...] w zastosowaniu dyrektywy using rozstrzyganie nazw odbywa się tak, jakby nazwy te zostały zadeklarowane w najmniejszym możliwym obszarze deklaracyjnym zawierającym zarówno przestrzeń nazw, jak i dyrektywę using."

To znaczy, że kompilator szukając wśród swoich słowników, usiłując rozszyfrować w skąd wziąć wartość danej zmiennej, szuka w najmniejszym mozliwym obszarze zawierającym i deklarację (using) i ustaloną przestrzeń nazw (tę w której się znajdujemy) czyli w tym przypadku obydwie te przestrzenie to globalna (bo wyższej od globalnej już nie ma). Czyli gdybyś zrobił co takiego:

usingnamespace Jill;
double fetch = 102;
double tmp = fetch + 2;

Kompilator zgłosi błąd - nie wie skąd wziąć fetch.
A zróbmy tak:

double fetch = 1000;
namespace Jill
{
    double fetch = 2;
}
 # include <iostream>
namespace A {
	double fetch = 100;
	namespace B{
using namespace Jill;

double tmp = fetch + 2;
	}
}
int main(void)
{
    std::cout << A::fetch << endl; // -> 100
    std::cout << ::fetch << endl;  // -> 1000
    std::cout << A::B::tmp;  // -> 102
        return 0;
}

Teraz się kompiluje i drukuje, jak widać, fetch z linijki double tmp = fetch + 2; jest brane z przestzreni nazw A, a fetch w słowniku globalnej pozostaje bez konfliktu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1