Dependency injection in C++

2019-01-21 16:51发布

This is also a question that I asked in a comment in one of Miško Hevery's google talks that was dealing with dependency injection but it got buried in the comments.

I wonder how can the factory / builder step of wiring the dependencies together can work in C++.

I.e. we have a class A that depends on B. The builder will allocate B in the heap, pass a pointer to B in A's constructor while also allocating in the heap and return a pointer to A.

Who cleans up afterwards? Is it good to let the builder clean up after it's done? It seems to be the correct method since in the talk it says that the builder should setup objects that are expected to have the same lifetime or at least the dependencies have longer lifetime (I also have a question on that). What I mean in code:

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;
    }
};

Now if there is a dependency that is expected to last longer than the lifetime of the object we are injecting it into (say ClassC is that dependency) I understand that we should change the build method to something like:

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

What is your preferred approach?

8条回答
贼婆χ
2楼-- · 2019-01-21 17:48

This is interesting, DI in C++ using templates:

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

I think the author is making the right moves as to not translate Java DI into C++ too literally. Worth the read.

查看更多
家丑人穷心不美
3楼-- · 2019-01-21 17:49

This talk is about Java and dependency injection.

In C++ we try NOT to pass RAW pointers around. This is because a RAW pointer have no ownership semantics associated with it. If you have no ownership then we don't know who is responsible for cleaning up the object.

I find that most of the time dependency injection is done via references in C++.
In the rare cases where you must use pointers, wrap them in std::unique_ptr<> or std::shared_ptr<> depending on how you want to manage ownership.
In case you cannot use C++11 features, use std::auto_ptr<> or boost::shared_ptr<>.

I would also point out that C++ and Java styles of programming are now so divergent that applying the style of one language to the other will inevitably lead to disaster.

查看更多
登录 后发表回答