2010-05-10 13 views
16

W C++, jaka jest rozdzielczość zakresu ("kolejność pierwszeństwa") dla nazw zmiennych shadowed? Nie mogę znaleźć w Internecie zwięzłej odpowiedzi.W C++, jaka jest rozdzielczość zakresu ("kolejność pierwszeństwa") dla shadowowanych nazw zmiennych?

Na przykład:

#include <iostream> 

int shadowed = 1; 

struct Foo 
{ 
    Foo() : shadowed(2) {} 

    void bar(int shadowed = 3) 
    { 
     std::cout << shadowed << std::endl; 
      // What does this output? 

     { 
      int shadowed = 4; 
      std::cout << shadowed << std::endl; 
       // What does this output? 
     } 
    } 

    int shadowed; 
}; 


int main() 
{ 
    Foo().bar(); 
} 

Nie mogę myśleć o innych zakresach, gdzie zmienna może konflikt. Daj mi znać, jeśli przegapię jedną.

Jaka jest kolejność priorytetów dla wszystkich czterech zmiennych shadow w funkcji członka?

+0

Możesz mieć blok kodu wewnątrz 'bar()', który również deklaruje 'shadowed'. –

+0

"Rozdzielczość zakresu" –

+0

Dodany przypadek dla bloku kodu wewnątrz 'bar()'. –

Odpowiedz

31

Twoje pierwszym przykładzie wyjścia 3. Twoje drugie wyjścia 4.

Ogólną zasadą jest, że wpływy z lookup „najbardziej lokalny” do zmiennej „najmniejszym lokalnym”. Dlatego pierwszeństwo to blok -> local -> class -> global.

Można również uzyskać dostęp każdy większość wersje zacienionej zmiennej extenso:

// See http://ideone.com/p8Ud5n 
#include <iostream> 

int shadowed = 1; 

struct Foo 
{ 
    int shadowed; 
    Foo() : shadowed(2) {} 
    void bar(int shadowed = 3); 
}; 

void Foo::bar(int shadowed) 
{ 
    std::cout << ::shadowed << std::endl; //Prints 1 
    std::cout << this->shadowed << std::endl; //Prints 2 
    std::cout << shadowed << std::endl; //Prints 3 
    { 
     int shadowed = 4; 
     std::cout << ::shadowed << std::endl; //Prints 1 
     std::cout << this->shadowed << std::endl; //Prints 2 
     //It is not possible to print the argument version of shadowed 
     //here. 
     std::cout << shadowed << std::endl; //Prints 4 
    } 
} 

int main() 
{ 
    Foo().bar(); 
} 
5

Należy wydrukować 3. Podstawową zasadą jest przede wszystkim na swój sposób pracy do tyłu pliku do najnowszej definicji kompilator byłby widoczny (edycja: nie wykracza poza zakres) i właśnie to wykorzystuje. W przypadku zmiennych, które są lokalne dla klasy, postępujemy zgodnie z tym samym z wyjątkiem, że wszystkie zmienne klasy są traktowane tak, jakby były zdefiniowane na początku definicji klasy. Zauważ, że jest to jednak bardziej lub mniej unikalne dla klas. Na przykład, biorąc pod uwagę kod jak:

int i; 

int x() { 
    std::cout << i << '\n'; // prints 0; 
    int i=1; 
} 

Nawet tam jesti to lokalny do funkcji, najnowsza definicja widać gdzie jest używany cout jest globalny, więc to, co i w tym wyrażeniu odnosi do. Gdyby jednak tak było w klasie:

int i; 

class X { 
    void y() { std::cout << i << "\n"; } 

    X() : i(2) {} 

    int i; 
}; 

Następnie wyrażenie cout odsyła do X::i choć jej definicja nie została jeszcze widoczne, gdy y jest analizowany.

+0

+1 Dobry punkt dotyczący zmiennych, które jeszcze nie zostały zadeklarowane. –

+0

"zmienne, które są lokalne dla klasy" Lepiej powiedzieć: zmienne, które należą do klasy_w klasie. – Melebius

Powiązane problemy