2010-01-18 15 views
11

Mam dwie klasyW jaki sposób używasz innego niż domyślny konstruktora dla członka?

class a { 
    public: 
     a(int i); 
}; 

class b { 
    public: 
     b(); //Gives me an error here, because it tries to find constructor a::a() 
     a aInstance; 
} 

Jak mogę to tak, że aInstance jest tworzony z (int i) zamiast próbować szukać domyślnego konstruktora? Zasadniczo chcę kontrolować wywoływanie konstruktora z wewnątrz konstruktora b.

+0

Zdaję sobie sprawę, że jest to przykład, a nie rzeczywisty kod, ale tylko ze względu na to, że ~~ jest jakością kodu pedantycznego ~, generalnie nie jest dobrym pomysłem uczynienie pól "publicznymi". Pewnie, są pewne przypadki użycia i nie jest to całkowicie nielegalne, ale zanim to zrobisz, upewnij się, że jest jakiś powód poza tym, że "to upraszcza część mojego kodu" ("to upraszcza dużo mojego kodu" jest całkowicie dopuszczalnym powodem , choć) –

Odpowiedz

20

Trzeba wezwać (int) wyraźnie w liście konstruktor inicjatora:

b() : aInstance(3) {} 

gdzie 3 jest wartość początkowa, którą chcesz użyć. Choć może to być jakaś int. Zobacz komentarze do ważnych uwag dotyczących zamówienia i innych zastrzeżeń.

+0

Wielkie dzięki. Myślałem, że to tylko do wywoływania konstruktorów klasy macierzystej. –

+1

Tak, można go również użyć do inicjowania członków. –

+0

W niektórych przypadkach konieczne jest zainicjowanie członków (np. Referencje) i tak można to zrobić. –

3

Użyj listy inicjalizacji:

b::b() : aInstance(1) {} 
0

Wystarczy użyć konstruktora, który jest zdefiniowany następująco:

class b { 
public: 
    b() 
    : aInstance(5) 
    {} 
    a aInstance; 
}; 
+1

To nie jest prawidłowe C++. –

+1

Ze zmienną składową działa to tylko wtedy, gdy zmienna jest "statyczną const", jak w 'static const int x (3);' –

+0

Faktycznie powinieneś zauważyć, że nie przekazuję stałej do konstruktora, ale innego członek b. Kiedy próbuję wykonać aInstance (c); interpretuje to jako definicję funkcji. –

-2

myślę, że należy użyć wskaźnika do 'a' jak:

class b { 
public: 
    b() : aInstance(new a(5)) {} 
    a *aInstance; 
}; 

W ten sposób będziesz mieć określone zachowanie. Oczywiście będziesz musiał zwolnić * aInstance w destruktorze.

+1

Przydział sterty jest bardzo niekorzystny w stosunku do alokacji stosu. W Twoim kodzie brakuje konstruktora kopiowania, operatora przypisania i destruktora. – GManNickG

+1

Zgadzam się. Z moim komentarzem byłem trochę za szybki, zwłaszcza, że ​​aInstance to tylko mały obiekt. Myślałem o rzeczywistych sytuacjach, w których obiekty mogłyby być większe, gdzie mógłbyś mieć leniwą inicjalizację, itp. Myślę, że ostatnio robiłem zbyt dużo C# i Java, gdzie prawie wszystko jest zrobione przez odniesienie;) –