2016-11-03 26 views
5

Przepraszam za niesamowicie tajemniczy tytuł.Dlaczego można zadowalać jawny argument konstruktora przy użyciu inicjowania elementu w konstruktorze?

Czytałem "Bardziej wyjątkowe C++" autorstwa Herb Sutter i natknąłem się na przykład na "liczony wskaźnik", nie wkleję całego kodu, ale on używa jawnego konstruktora z podpisem:

explicit countedPointer(P* obj): p(new impl(obj)) {} 

Ponadto deklaruje klasę, która ma liczone wskaźnikiem obiektu jako prywatnej członka klasy, w konstruktorze tej klasy, on inicjuje jego liczony wskaźnik jak tak:

flagNth(n):pimpl_(new flagNthImpl(n)) {} 

gdzie, pimpl_ jest obiektem licznika, tzn.

countedPointer<flagNthImpl>pimpl_; 

Próbowałem uruchomić ten kod i wewnątrz main.cpp, gdy próbuję wykonać następujące czynności pojawia się błąd (oczywiście, ponieważ konstruktor jest jawne)

int main(int argc, const char * argv[]) 
{ 
    countedPointer<int> cp = new int(5); 
} 

Moje pytanie brzmi, dlaczego można to zrobić na liście inicjalizacji członów konstruktora? Czy inicjalizacja różni się od regularnej inicjalizacji, a jeśli tak, to w jaki sposób?

Dziękujemy!

+2

'pimpl_ (nowe flagNthImpl (n))' jest taki sam jak 'countedPointer CP (new int) (5)' – NathanOliver

+0

'countedPointer cp = nowy int (5);' jest przydział, a nie inicjalizacji ' countedPointer cp (new int (5)); 'jest taki sam jak składnia klas i powinno działać. – djgandy

+3

@djgandy To zdecydowanie zdecydowanie ** nie ** zadanie. To inicjalizacja kopiowania, ale wciąż jest ** inicjalizacja **. – Angew

Odpowiedz

6

To będzie pracować dla Ciebie w main:

countedPointer<int> cp(new int(5)); 

To bezpośredni inicjalizacji i by wywołać konstruktora normalnie.

jednak robisz to:

countedPointer<int> cp = new int(5); 

to kopia inicjalizacji i że nie działa z jawnych konstruktorów. Aby z powodzeniem używać kopii inicjalizacji z wyraźną konstruktora, to trzeba to:

countedPointer<int> cp = countedPointer<int>(new int(5)); 

Oczywiście, jesteś ogólnie lepiej wyłączyć za pomocą bezpośredniego inicjalizacji (jak w pierwszym przykładzie) lub bezpośredni lista inicjalizacji:

countedPointer<int> cp{new int(5)}; 
+0

To ma sens. Czy inicjalizacja obiektu wewnątrz konstruktora jest w istocie bezpośrednią inicjalizacją? – rmadhwal

+0

@rmadhwal Tak, inicjalizacja na liście inicjalizatorów pamięci jest zawsze bezpośrednią inicjalizacją lub bezpośrednią inicjalizacją listy. – Angew