wtrysk zależność w C ++

głosy
23

Jest to również kwestia, że poprosiłem w komentarzu w jednym z Miśko Hevery w google rozmowach , że miał do czynienia z Dependency Injection ale został pochowany w komentarzach.

Zastanawiam się, w jaki sposób krok fabryka / budowniczym okablowanie zależności razem mogą pracować w C ++.

Czyli mamy klasy A, który zależy od B. budowniczy przeznaczy B w stercie, przekazać wskaźnik do B w konstruktora jest jednocześnie przeznaczając na stercie i zwraca wskaźnik do A.

Kto sprząta potem? Czy to dobrze, niech budowniczy posprzątać po to się robi? To wydaje się być właściwa metoda, gdyż w rozmowie mówi, że budowniczy powinien Ustawienia obiektów, które będą mieć taką samą żywotność lub przynajmniej Zależności mają dłuższą żywotność (Mam również pytanie o to). Co to znaczy w kodzie:

class builder {
public:
    builder() :
        m_ClassA(NULL),m_ClassB(NULL) {
    }
    ~builder() {
        if (m_ClassB) {
            delete m_ClassB;
        }
        if (m_ClassA) {
            delete m_ClassA;
        }
    }
    ClassA *build() {
        m_ClassB = new class B;
        m_ClassA = new class A(m_ClassB);
        return m_ClassA;
    }
};

Teraz, jeśli istnieje zależność, że oczekuje się, aby trwać dłużej niż okres istnienia obiektu jesteśmy wstrzykiwanie go do (słownie ClassC jest to, że zależność) Rozumiem, że należy zmienić sposób gromadzeniu się coś podobnego:

ClassA *builder::build(ClassC *classC) {
    m_ClassB = new class B;
    m_ClassA = new class A(m_ClassB, classC);
    return m_ClassA;
}

Jaki jest Twój preferowany podejście?

Utwórz 09/12/2008 o 15:26
źródło użytkownik
W innych językach...                            


8 odpowiedzi

głosy
2

Wszystko się komplikuje, jeśli nie rozstrzygać w kwestii własności raz na zawsze. Będziesz po prostu trzeba podjąć decyzję w implementacji, czy to możliwe, że żyją dłużej niż Zależności obiektów są wstrzykiwane do.

Osobiście powiedziałbym, no: obiekt w którym zależność jest wstrzykiwany będzie posprzątać po nim. Próbuje zrobić to przez producenta oznacza, że ​​budowniczy będą musieli żyć dłużej niż zarówno uzależnienia i obiektu, do którego jest on wstrzykiwany. To powoduje więcej problemów niż rozwiązuje, moim zdaniem, bo budowniczy nie służy żadnej bardziej pożytecznym celom po konstrukcja z wtryskiem zależność została zakończona.

Odpowiedział 09/12/2008 o 15:33
źródło użytkownik

głosy
13

Ta rozmowa jest o Java i wstrzykiwania zależności.

W C ++ staramy NIE przekazać wskaźniki wokół RAW. To dlatego, że nie mają wskaźnik RAW semantykę własności z nim związane. Jeśli nie masz własności potem nie wiemy, kto jest odpowiedzialny za sprzątanie obiektu.

Uważam, że większość wstrzykiwania zależności czasu odbywa się za pomocą odniesień w C ++.
W rzadkich przypadkach, gdy trzeba użyć wskaźników, zawinąć je w std :: unique_ptr <> lub std :: shared_ptr <> w zależności od tego, jak chcesz zarządzać własności.
W przypadku, gdy nie można użyć c ++ 11 funkcji, należy użyć std :: auto_ptr <> lub boost :: shared_ptr <>.

Chciałbym również podkreślić, że C ++ i Java style programowania są teraz tak rozbieżne, że stosowanie styl jednego języka na drugi nieuchronnie doprowadzi do katastrofy.

Odpowiedział 09/12/2008 o 15:47
źródło użytkownik

głosy
2

W C ++, normalnie, kiedy zrobiłeś to dobrze, nie trzeba pisać destruktorów w ogóle w większości przypadków. Należy używać inteligentne kursory automatycznie usuwać rzeczy. Myślę, budowniczy nie wygląda właściciela instancji ClassA i ClassB. Jeśli nie chcesz używać inteligentnych wskaźników, warto pomyśleć o czasie życia obiektów i ich właścicieli.

Odpowiedział 09/12/2008 o 16:14
źródło użytkownik

głosy
3

Użyj RAII.

Przekazanie surowego wskaźnik do kogoś jest taka sama jak wręczając im własności. Jeśli to nie to, co chcesz zrobić, to należy dać im jakąś elewacji że wie również, jak oczyścić przedmiotu.

shared_ptr <> Można to zrobić; drugi argument konstruktora może być obiektem funkcja, która wie, jak usunąć obiekt.

Odpowiedział 09/12/2008 o 17:40
źródło użytkownik

głosy
9

To ciekawe, DI w C ++ przy użyciu szablonów:

http://adam.younglogic.com/?p=146

Myślę, że autor jest podejmowanie właściwych ruchów, aby nie tłumaczyć Java DI w C ++ zbyt dosłownie. Warto przeczytać.

Odpowiedział 23/12/2009 o 02:08
źródło użytkownik

głosy
2

Na podstawie własnego doświadczenia, najlepiej jest mieć jasne zasady własności. Dla małych konkretnych przedmiotów, najlepiej jest korzystać z kopią do uniknięcia wzajemnego uzależnienia.

Czasami krzyż zależność jest nieuniknione i nie ma wyraźnego własność. Na przykład, (m), przykłady A własny (n), przykłady B i pewne przypadki B mogą należeć do wielu jako. W tym przypadku najlepszym rozwiązaniem jest zastosowanie liczenia odniesienia do B, w sposób podobny do liczenia odniesienia COM. Wszelkie funkcje, które biorą w posiadanie B * musi zwiększyć liczbę odwołań pierwszy i zmniejszenie jej podczas zwalniania zawodnika.

Ja również unikać używania boost :: shared_ptr gdyż tworzy nowy typ (shared_ptr ib * stać dwa różne rodzaje). Okazało się, że to przynosi więcej bólu głowy, gdy dodam metod.

Odpowiedział 23/12/2009 o 17:04
źródło użytkownik

głosy
6

Ja niedawno bakcyla DI. Myślę, że to rozwiązuje wiele problemów złożoność, zwłaszcza zautomatyzowanej części. Pisałem prototyp, który pozwala używać DI w ładnej C ++ sposób, a przynajmniej tak mi się wydaje. Można spojrzeć na przykład kod tutaj: http://codepad.org/GpOujZ79

Rzeczy, które są oczywiście nie brakuje: scoping, bez wiązania z interfejsem do realizacji. Ten ostatni jest dość łatwe do rozwiązania, to pierwsze, nie mam pojęcia.

Byłbym wdzięczny, gdyby ktoś tu ma swoje zdanie na kodzie.

Odpowiedział 10/05/2010 o 17:39
źródło użytkownik

głosy
1

Można również sprawdzić wtrysk FFEAD Dependency . Zapewnia DI na liniach wiosny dla Java i ma non natrętny sposób radzenia sobie z rzeczami. Ma także wiele innych ważnych funkcji, takich jak wbudowany AJAX wsparcia, refleksji, serializacji, C ++ tłumacza Business Components dla C ++, ORM, Messaging, Web-Services, nitki Baseny i serwerem aplikacji , która obsługuje wszystkie te funkcje.

Odpowiedział 10/08/2010 o 08:31
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more