Najpierw wyjaśnię, czym jest lista inicjalizacji pamięci . Lista inicjalizatorów memów to rozdzielona przecinkami lista inicjalizatorów memów, gdzie każdy inicjator pamięci jest nazwą składową (
, po której następuje lista-wyrażeń , po której następuje znak )
. Lista wyrażeń to sposób konstruowania elementu członkowskiego. Na przykład w
static const char s_str[] = "bodacydo";
class Example
{
private:
int *ptr;
string name;
string *pname;
string &rname;
const string &crname;
int age;
public:
Example()
: name(s_str, s_str + 8), rname(name), crname(name), age(-4)
{
}
};
mem-inicjator-lista konstruktora dostarczone przez użytkownika, nie-argumentów name(s_str, s_str + 8), rname(name), crname(name), age(-4)
. Ten MEM inicjator wykazie oznacza, że name
element jest inicjowane przez przez std::string
konstruktora, które ma dwa iteratorami wejściowych The rname
element jest inicjowane z odniesieniem do name
The crname
element jest inicjowany const odniesieniem do name
, a age
element jest inicjalizowany wartością -4
.
Każdy konstruktor ma swoją własną listę inicjalizatorów memów , a elementy członkowskie mogą być inicjowane tylko w określonej kolejności (zasadniczo w kolejności, w której elementy członkowskie są zadeklarowane w klasie). W ten sposób członkowie Example
można zainicjować tylko w kolejności: ptr
, name
, pname
, rname
, crname
, i age
.
Jeśli nie określisz inicjalizatora pamięci elementu członkowskiego, standard C ++ mówi:
Jeśli jednostka jest niestatycznym składnikiem danych ... typu klasy ..., jednostka jest inicjowana domyślnie (8.5). ... W przeciwnym razie jednostka nie zostanie zainicjowana.
W tym przypadku, ponieważ name
jest to niestatyczny element członkowski danych typu klasy, jest inicjowany domyślnie, jeśli nie name
określono inicjatora dla w mem-initializer-list . Wszyscy pozostali członkowie Example
nie mają typu klasy, więc nie są inicjowani.
Gdy standard mówi, że nie są one zainicjalizowane, oznacza to, że mogą mieć dowolną wartość. Tak więc, ponieważ powyższy kod nie został zainicjalizowany pname
, może to być wszystko.
Zauważ, że nadal musisz przestrzegać innych reguł, takich jak reguła, że odwołania zawsze muszą być inicjowane. Brak inicjalizacji odwołań jest błędem kompilatora.