2010-11-10 11 views
6

mój kod:"podaje" odwołanie do "tego" wewnątrz konstruktora w porządku?

Scene::Scene(const std::string &scene_file) : ambient_light(0, 0, 0), background(0, 0, 0){ 
    scene_parser parser(*this); 
    parser.parse(scene_file); 
} 

scene_parser jest przyjacielem sceny, aw sposobie przetworzy go dostępów (R/W) członkowie Scene. Czy to spowoduje jakieś problemy?

+0

Należy zauważyć, że jest to OK, o ile podajesz wskaźnik "this" z poziomu ciała konstruktora, a nie listy inicjalizacyjnej. –

+0

sprawdź także, co C++ faq-lite ma do powiedzenia: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.7 – stefaanv

Odpowiedz

4

W twoim konkretnym przykładzie nie powinno być problemów.

Zasadniczo problemem z wydaniem odniesień this jest to, że okresy życia obu obiektów nie są dokładnie wyrównane, a drugi obiekt może próbować uzyskać dostęp do obiektu, do którego się odnosi, po jego zniszczeniu.

W twoim przykładzie obiekt scene_parser znajduje się na stosie, więc jego koniec życia kończy się na końcu konstruktora Scene. Nie ma możliwości, aby mógł on uzyskać dostęp do nieistniejącego obiektu za pośrednictwem podanego odniesienia, więc nie mogą wystąpić żadne problemy.

+3

Nie, ale jeśli 'parser' wywoła funkcje' virtual', nie uzyskasz pożądanego efektu. Chociaż * jest * legalne, możesz (i prawdopodobnie powinieneś) wziąć pod uwagę ten błąd. –

+0

To jest potencjalny problem z podawaniem jakichkolwiek wskaźników w ogóle, nic specyficznego dla konstruktorów lub "tego" wskaźnika. Prawdziwym problemem z oddaniem 'tego' od konstruktora jest to, że funkcje klasy mogą być wywołane zanim konstruktor zakończy tworzenie niezmienników. –

+1

Nie zamierzam tworzyć podklas Sceny, więc wygląda na to, że wszystko jest w porządku. – Bwmat

8

Tak, można podać odniesienie do this. Zazwyczaj jednak chcesz to zrobić, gdy drugi obiekt użyje wskaźnika później. Twój przypadek użycia wygląda tak, jakby natychmiast użył Scene, zanim konstruktor ukończy, co jest bardzo śliskie.

W tej chwili nie tworzysz żadnych niezmienników po wywołaniu parse, więc powinno być dobrze, ale jest również delikatne i łatwe do wprowadzenia w przyszłości zmian w celu złamania.

+0

Dobra odpowiedź. Myślę, że powinieneś uwzględnić niektóre informacje, które dostarczyłeś w komentarzach, do innych odpowiedzi, ponieważ wydaje się, że są pewne subtelności, którymi należy się zająć. –

+2

@voodooclock: Ograniczenia związane z funkcjami wirtualnymi faktycznie nie wymagają przekazania tego "wskaźnika" do żadnego innego obiektu. Możesz dostać się w kłopoty wywołując własne funkcje klasy z wnętrza konstruktora. Poza tym OP już wskazał, że 'Scena' jest klasą końcową, więc dynamiczny typ obiektu nie będzie problemem. –

+0

Ah, dzięki za wyjaśnienie - zbyt dużo czytałem. –

1

To zależy.

Wewnątrz korpusu konstruktora (tj. Po wykonaniu listy inicjalizatorów) obiekt jest uważany za "w pełni skonstruowany" do bieżącego typu. W związku z tym można może odniesienia , ale wszelkie wywołania funkcji funkcji virtual nie będą korzystać z funkcji overrided w klasach pochodnych.

+2

Myślę, że dostałeś to w tył na połączenia do funkcji wirtualnych, ale jest to ważna rzecz, o której należy pamiętać. –

+0

@Ben: masz rację, wpisałem "podstawową" zamiast "pochodną". –

0

Wszystkie Twoje podobiekty (członkowie i zasady) są konstruowane przez pierwszą instrukcję w treści konstruktora. Jeśli twój obiekt jest w "stanie prawidłowym" (który jest częścią definicji twojej klasy, czasami nazywanej "niezmiennikiem klasy") w tym miejscu, możesz traktować go jako w pełni skonstruowany obiekt i robić z nim cokolwiek. Jednak wyszukiwanie wirtualne działa nieco inaczej, niż można się spodziewać lub wymaga: jeśli jest to klasa podstawowa (a zatem ten obiekt jest podobiektem czegoś innego), ostateczny typ nie został jeszcze "przypisany". Na przykład jest to jeden ze sposobów wywoływania metod czysto wirtualnych i otrzymania błędu środowiska wykonawczego (jeśli te metody nie mają żadnych definicji).

Bardziej interesującą sytuacją jest użycie tego w inicjatorze konstruktora; to ma pewne zastrzeżenia, ale to także przed ciałem konstruktora.

Powiązane problemy