2015-04-17 14 views
9

Zajmuję się C++ i jest jedna funkcja językowa, z którą mam szczególny kłopot.Niejawnie skonstruowane zmienne w C++

Przywykłem do deklarowania i inicjalizacji zmiennej wyraźnie, ale w C++ czasami wydaje się zadeklarować i niejawnie skonstruować zmiennej.

Na przykład w tym urywku rdev wydaje się być niejawnie skonstruowany (ponieważ jest następnie używany do skonstruowania domyślnej_adresu);

random_device rdev; 
default_random_engine gen(rdev()); 

Czy ktoś może wyjaśnić, co się tutaj dzieje? Jak mogę to odróżnić od zwykłej deklaracji, takiej jak int myInt;?

+0

Wszystkie świetne odpowiedzi, dzięki. Zaakceptowałem odpowiedź @ Puppy, ponieważ wyjaśnił, dlaczego int jest nieco inny, używając prostych łatwych słów;), ale szczegóły techniczne w innych odpowiedziach są również bardzo pomocne. – Giswok

Odpowiedz

4

Może ktoś wyjaśnić, co tu się dzieje? Jak mogę to odróżnić od prostej deklaracji, takiej jak int myInt;

Są to proste definicje.

Jedyna różnica polega na właściwościach tego typu. random_device musi zostać skonstruowany, więc tak jest. int ma, ale ludzie płaczą za dużo, więc tak nie jest. Szczerze mówiąc, zachowanie w stylu int jest bardziej defektem językowym niż czymś, czego naprawdę chcesz.

Ostatecznie jest to właściwość typów, a nie definicji.

5

Czy ktoś może wyjaśnić, co się tutaj dzieje?

Są to definicje, a nie tylko deklaracje. Definicja zmiennej tworzy zmienną. W pierwszym przypadku nie ma inicjalizatora, co oznacza, że ​​powinien on zostać zainicjowany domyślnie.

Jak mogę to odróżnić oprócz zwykłej deklaracji, takiej jak int myInt;?

To także definicja, tworząc zmienną int i pozostawiając ją niezainicjowaną.

Można zadeklarować zmienną globalną bez definiowania go:

extern int myInt; 

extern wskazuje, że ma powiązania zewnętrzne, a określa się gdzieś indziej. Inne rodzaje zmiennych nie mogą być zadeklarowane bez ich zdefiniowania.

+0

Czy są one liczone jako definicje? W rzeczywistości nic nie definiujesz, po prostu deklarujesz zmienną i dostajesz trochę pamięci. –

+0

@JID: Tak, są to definicje, które definiują zmienne. Jest to definicja, która powoduje przydzielenie pamięci i zainicjowanie zmiennej. –

+0

tak po prostu to sprawdziłem i masz rację :) –

5
random_device rdev; // creates an instance of random_device on the stack 
        // with default constructor (taking no arguments) 

default_random_engine gen( // creates an instance of default_random_engine 
          // on the stack 
    rdev()     // passing it the result of 
          // invocation of operator '()' 
          // on the instance rdev of random_device 
); 

samo w bardziej opisowym postaci (niektóre C++ 11):

auto rdev = random_device {}; 
auto gen = default_random_engine { rdev.operator()() }; 
3

Jak stwierdzono w C++ Standard (8.05.11): If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. — end note ]

To jest dokładnie to twoja sprawa: zmienna definicja bez wyraźnej inicjatora. Więc zobaczmy, co default-initialized środki (8.5.7):

To default-initialize an object of type T means: 
    — if T is a (possibly cv-qualified) class type (Clause 9), 
    the default constructor for T is called 
    (and the initialization is ill-formed if T has no accessible default constructor); 
— if T is an array type, each element is default-initialized; 
— otherwise, no initialization is performed. 

To wyraźnie stwierdza różnicę pomiędzy swoimi dwoma przykładami:

  • random_device jest typem klasy, więc domyślnego konstruktora (jeden bez argumentów) jest domyślnie wywoływana.
  • int nie jest ani typem klasy, ani rodzajem tablicowym, więc nie jest wykonywana inicjalizacja i będzie mieć nieokreśloną wartość, dopóki nie zostanie jawnie zainicjowana (poprzez przypisanie jej wartości).