Dependency injection std::shared_ptr vs reference

Let's say we have a class Buffer, a class BufferAnalyzer, and a glue class Application. Class Application has an instance of Buffer and BufferAnalyzer in it. BufferAnalyzer's has an object of type Buffer in it.

My question is should BufferAnalyzer contain a reference to Buffer (this is the style that I've seen in "Programming -- Principles and Practise Using C++" by Bjarne Stroustrup in the code examples) or should it contain a std::shared_ptr (which would decouple the code making classes more reusable)?

Pros of using a reference:
We know that Application controls the life of both Buffer and BufferAnalyzer.

Cons of using a reference:
Classes are tightly coupled and cannot be reused directly without modification.

Pros of using a std::shared_ptr:
Loosely coupled design making classes very resuable.

Cons of using a std::shared_ptr:
I really haven't seen std::shared_ptr used anywhere. All the code that I have seen uses references. In my opinion in C++ it just feels natural to use a reference.
Last edited on
What makes you think classes are more tightly coupled when using a reference than when using a smart pointer?
If you use a reference you have to make sure that Buffer does not go out of scope while BufferAnalyzer is still using it. My colleagues said that I should use a std::shared_ptr for that reason, but I still disagree with them and prefer to use a reference. So I wanted a second opinion.
Last edited on
I see no issue with reusability either way. The advantage of pointers is the ability to decouple dependencies so that you can use forward references in header files. There is a decoupling advantage of pointers but I don't see how it has anything to do with whether something is more or less reusable. In implementation is either reusable or it isn't regardless of whether the user of it has a pointer or a reference to it. In large scale projects this is critical as you can reduce compile times and allow development to interfaces. In that sense, I generally prefer the pimpl idiom ( http://en.wikipedia.org/wiki/Opaque_pointer ) for that advantage. Additionally some patterns are much easier and better to implement with pointers to implementations. I rarely if ever use references as class attributes.
If you use a reference you have to make sure that Buffer does not go out of scope while BufferAnalyzer is still using it.

That's true.

My colleagues said that I should use a std::shared_ptr for that reason, but I still disagree with them and prefer to use a reference.

I don't see a reason for using a shared pointer. In this case it's pretty clear the ownership of the object belongs to the Application class, which can ensure the buffer exists when the analyzer is active. Shared pointers are great for shared ownership, but I don't see a reason for ownership to be shared here. In fact, requiring the analyzer to share ownership results in less reusability. You must jump through hoops to use a buffer of automatic duration if shared ownership is required by the analyzer.


kempofighter wrote:
The advantage of pointers is the ability to decouple dependencies so that you can use forward references in header files.

References and pointers are alike in this particular fashion.


References and pointers are alike in this particular fashion.

I stand corrected on that point. Thanks. As I remember; references have to be initialized to something which can't be null which is advantageous in some cases, whereas pointers can be initialized as null and assigned at some later time. After trying an example, I remember now why I don't like references as class attributes. Evidently they have to be initialized in the initializer list which doesn't allow for any flexibility. It can't be done in the body of the constructor or in a common initialize function that could be called by multiple constructors. Therefore using a reference is quite tricky or impossible if you are implementing a pattern such as bridge or abstract factory or in any situation where you need to defer the assignment of an object pointer. I think that references in API calls are great, but as class attributes they always seem to just limit what is possible.
Last edited on
In fact the more I think about it the more using a reference seems like the right thing to do. The life of Buffer clearly depends on the life of Application, using a std::shared_ptr and allocating on the free store seems absolutely redundant in this case. Someone someday might take class BufferAnalyzer and see that it takes a std::shared_ptr and be like: what's going on here, why do I need to share ownership, what's BufferAnalyzer going to do that it need to share ownership? Where as if you use a reference you keep the interface (of the constructor) simple and straight forward to the users of that class without overcomplicating things unnecessarily. One of the core things I learned of the book "Programming" by Stroustrup is to keep things simple, as simple as possible, but not simpler. The people I worked with on that project were working with Java mainly and apparently they wanted to put the philosophy of that language in C++. In this case why do you have to do your own memory management (using smart pointers and allocating on the free store) when you can use the stack and RAII (thus keeping it simple)? And also no design patterns were used for Buffer, BufferAnalyzer, and Application so using a reference limits the possibility to swap one implementation with another at runtime as it should be because that is the logic of the program.

Side note: We completed the project a long time ago and used std::shared_ptr, but this dilemma was still bothering me inside, whether to use a std::shared_ptr or a reference.
Last edited on
Topic archived. No new replies allowed.