I am going back to C++ after spending some time in memory-managed languages, and I'm suddently kinda lost as to what is the best way to implement dependency injection. (I am completely sold to DI because I found it to be the simplest way to make test-driven design very easy).
Now, browsing SO and google got me quite a number of opinions on the matter, and I'm a bit confused.
As an answer to this question, Dependency injection in C++ , someone suggested that you should not pass raw pointers around, even for dependency injection. I understand it is related to ownership of the objects.
Now, ownership of objects is also tackled (although not into enough details to my state ;) ) in the infamous google style guide : http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Smart_Pointers
So what I understand is that in order to make it clearer which object has ownership of which other objects, you should avoid passing raw pointers around. In particular, it seems to be against this kind of coding :
class Addict {
// Something I depend on (hence, the Addict name. sorry.)
Dependency * dependency_;
public:
Addict(Dependency * dependency) : dependency_(dependency) {
}
~Addict() {
// Do NOT release dependency_, since it was injected and you don't own it !
}
void some_method() {
dependency_->do_something();
}
// ... whatever ...
};
If Dependency is a pure virtual class (aka poor-man's-Interface ), then this code makes it easy to inject a mock version of the Dependency (using something like google mock).
The problem is, I don't really see the troubles I can get in with this kind of code, and why I should want to use anything else than raw pointers ! Is it that it is not clear where the dependency comes from?
Also, I read quite a few posts hinting that one should really be using references in this situation, so is this kind of code better?
class Addict {
// Something I depend on (hence, the Addict name. sorry.)
const Dependency & dependency_;
public:
Addict(const Dependency & dependency) : dependency_(dependency) {
}
~Addict() {
// Do NOT release dependency_, since it was injected and you don't own it !
}
void some_method() {
dependency_.do_something();
}
// ... whatever ...
};
But then I get other, equally authoritive advices against using references as member: http://billharlan.com/pub/papers/Managing_Cpp_Objects.html
As you can see I am not exactly sure about the relative pros and cons of the various approaches, so I am a bit confused. I am sorry if this has been discussed to death, or if it is only a matter of personnal choice and consistency inside a given project ... but any idea is welcome.
Answers summary
(I don't know if it is good SO-tiquette to do this, but I'll add code example for what I gathered from answers...)
From the various responses, here's what I'll probably end up doing in my case:
pass dependencies as reference (at least to make sure NULL is not possible)
in the general case where copying is not possible, explicitly disallow it, and store dependencies as reference
in the rarer case where copying is possible, store dependencies as RAW pointers
let the creator of the dependencies (factory of some kind) decide between stack allocation or dynamic allocation (and in the latter case, management through a smart pointer)
establish a convention to separate dependencies from own resources
So I would end up with something like:
class NonCopyableAddict {
Dependency & dep_dependency_;
// Prevent copying
NonCopyableAddict & operator = (const NonCopyableAddict & other) {}
NonCopyableAddict(const NonCopyableAddict & other) {}
public:
NonCopyableAddict(Dependency & dependency) : dep_dependency_(dep_dependency) {
}
~NonCopyableAddict() {
// No risk to try and delete the reference to dep_dependency_ ;)
}
//...
void do_some_stuff() {
dep_dependency_.some_function();
}
};
And for a copyable class:
class CopyableAddict {
Dependency * dep_dependency_;
public:
// Prevent copying
CopyableAddict & operator = (const CopyableAddict & other) {
// Do whatever makes sense ... or let the default operator work ?
}
CopyableAddict(const CopyableAddict & other) {
// Do whatever makes sense ...
}
CopyableAddict(Dependency & dependency) : dep_dependency_(&dep_dependency) {
}
~CopyableAddict() {
// You might be tempted to delete the pointer, but its name starts with dep_,
// so by convention you know it is not your job
}
//...
void do_some_stuff() {
dep_dependency_->some_function();
}
};
From what I understood, there is no way to express the intent of "I have a pointer to some stuff, but I don't own it" that the compiler can enforce. So I'll have to resort to naming convention here...
Kept for reference
As pointed out by Martin, the following example does not solve the problem.
Or, assuming I have a copy constructor, something like:
class Addict {
Dependency dependency_;
public:
Addict(const Dependency & dependency) : dependency_(dependency) {
}
~Addict() {
// Do NOT release dependency_, since it was injected and you don't own it !
}
void some_method() {
dependency_.do_something();
}
// ... whatever ...
};
There is no hard and fast rule:
As people have mentioned using references inside objects can cause copy problems (and it does) so it is not a panacea, but for certain situation it can be useful (that is why C++ gives us the option to do it all these different ways). But using RAW pointers is really not an option. If you are dynamically allocating objects then you should always be maintaining them with smart pointers and your object should also be using smart pointers.
For people who demand examples: Streams are always passed and stored as references (as they can't be copied).
Some Comments on your code examples:
Example one and two
Your first example with pointers. Is basically the same as the second example using references. The difference being that a reference can not be NULL. When you pass a reference the object is already alive and thus should have a lifespan greater than the object you are testing already (If it was created on the stack) so it should be safe to keep a reference. If you are dynamically creating pointers as dependencies I would consider using boost::shared_pointer or std::auto_ptr depending if ownership of the dependency is shared or not.
Example Three:
I don't see any great use for your third example. This is because you can not use polymorphic types (If you pass an object derived from Dependency it will be sliced during the copy operation). Thus the code may as well be inside Addict rather than a separate class.
Bill Harlen: (http://billharlan.com/pub/papers/Managing%5FCpp%5FObjects.html)
Not to take anything away from Bill But:
I have never heard of him.
He is a Geo-Physists not a computer programmer
He recomends programming in Java to improve your C++
The languages are now so different in usage that is utterly false).
If you want to use references of What to-do/not to-do.
Then I would pick one of the Big names in the C++ field:
Stroustrup/Sutter/Alexandrescu/Meyers
Summary:
Don't use RAW pointers (when ownership is required)
Do use smart pointers.
Don't copy objects into your object (it will slice).
You can use references (but know the limitations).
My example of Dependency injection using references:
class Lexer
{
public: Lexer(std::istream& input,std::ostream& errors);
... STUFF
private:
std::istream& m_input;
std::ostream& m_errors;
};
class Parser
{
public: Parser(Lexer& lexer);
..... STUFF
private:
Lexer& m_lexer;
};
int main()
{
CLexer lexer(std::cin,std::cout); // CLexer derived from Lexer
CParser parser(lexer); // CParser derived from Parser
parser.parse();
}
// In test.cpp
int main()
{
std::stringstream testData("XXXXXX");
std::stringstream output;
XLexer lexer(testData,output);
XParser parser(lexer);
parser.parse();
}
Summary: If you need to store a reference, store a pointer as a private variable and access it through a method which dereferences it. You can stick a check that the pointer isn't null in the object's invariant.
In depth:
Firstly, storing references in classes makes it impossible to implement a sensible and legal copy constructor or assignment operator, so they should be avoided. It is usually a mistake to use one.
Secondly, the type of pointer/reference passed in to functions and constructors should indicate who has responsibility for freeing the object and how it should be freed:
std::auto_ptr - the called function is responsible for freeing, and will do so automatically when it's done. If you need copy semantics, the interface must provide a clone method which should return an auto_ptr.
std::shared_ptr - the called function is responsible for freeing, and will do so automatically when it's done and when all other references to the object are gone. If you need shallow copy semantics the compiler generated functions will be fine, if you need deep copying the interface must provide a clone method which should return a shared_ptr.
A reference - the caller has responsibility. You don't care - the object may be stack allocated for all you know. In this case you should pass by reference but store by pointer. If you need shallow copy semantics the compiler generated functions will be fine, if you need deep copying you're in trouble.
A raw pointer. Who knows? Could be allocated anywhere. Could be null. You might be responsible for freeing it, you might not.
Any other smart pointer - it should manage the lifetime for you, but you'll need to look at the documentation to see what the requirements are for copying.
Note that the methods which give you responsibility for freeing the object don't break DI - freeing the object is simply a part of the contract you have with the interface (as you don't need to know anything about the concrete type to free it).
I would steer clear of references as members since they tend to cause no end of headaches if you end up sticking one of your objects in an STL container. I would look into using a combination of boost::shared_ptr for ownership and boost::weak_ptr for dependents.
[update 1]
If you can always guarantee the dependency outlives the addict, you can use a raw pointer/reference, of course. between these two, I'd make a very simple decision: pointer if NULL is allowed, reference otherwise.
(The point of my original post was that neither pointer nor reference solve the lifetime problem)
I'd follow the infamous google style guideline here, and use smart pointers.
Both a pointer and a reference have the same problem: you need to make sure the dependency outlives the addict. That pushes a quite nasty responsibility onto the client.
With a (reference-counted) smart pointer, the policy becomes dependency is destroyed when noone uses it anymore. Sounds perfect to me.
Even better: with boost::shared_ptr (or a similar smart pointer that allows a type-neutral destruction policy) the policy is attached to the object at construction - which usually means everything affecting the dependency ends up in a single place.
The typical problems of smart pointers - overhead and circular references - rarely come into play here. Dependency instances usually aren't tiny and numerous, and a dependency that has a strong reference back to its addicts is at least a code smell. (still, you need to keep these things in mind. Welcome back to C++)
Warning: I am not "totally sold" to DI, but I'm totally sold on smart pointers ;)
[update 2]
Note that you can always create a shared_ptr to a stack/global instance using a null deleter.
This requires both sides to support this, though: addict must make guarantees that it will not transfer a reference to the dependency to someone else who might live longer, and caller is back with the responsibility ensuring lifetime. I am not to happy with this solution, but have used this on occasion.
But then I get other, equally authoritive advices against using references as member : http://billharlan.com/pub/papers/Managing%5FCpp%5FObjects.html
In this case I think you only want to set the object once, in the constructor, and never change it so no problem.
But if you want to change it later on, use an init function, have a copy constructor, in short everything that would have to change the reference you will have to use pointers.
It has been asked before, but my SO search skills are not up to finding it. To summarise my position - you should very rarely, if ever, use references as class members. Doing so causes all sorts of initialisation, assignment and copying problems. Instead, use a pointer or a value.
Edit: Found one - this is a question with a variety of opinions as answers: Should I prefer pointers or references in member data?
I can here my downmoderation coming already, but I will say that there should be no reference members in a class FOR ANY REASO, EVER. Except if they are a simple constant value. The reasons for this are many, the second you start this you open up all the bad things in C++. See my blog if you really care.
Related
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
I wish to create a class (class1) which contains another class (class2) as a data member. I then want class2 to know about class1 and be able to communicate with it.
I could have a reference to class1 as a member in class2 but that then means I need to provide a reference to class1 as a parameter in the constructor of class2 and use initialiser lists which I don't want. I'm trying to do this without needing the constructor to do it.
I would like for class2 to have a member function called Initialise which could take in the reference to class1, but this seems impossible without using pointers. What would people recommend here? Thanks in advance.
The code is completely simplified just to get the main idea across :
class class1
{
public:
InitialiseClass2()
{
c2.Initialise(this);
}
private:
class2 c2;
};
class class2
{
public:
Initialise(class1* c1)
{
this->c1 = c1;
}
private:
class1* c1;
};
this seems impossible without using pointers
That is incorrect. Indeed, to handle a reference to some other object, take a reference into a constructor:
class class2
{
public:
class2(class1& c1)
: c1(c1)
{}
private:
class1& c1;
};
The key here is to initialise, not assign, the reference. Whether this is possible depends on whether you can get rid of your Initialise function and settle into RAII (please do!). After that, whether this is actually a good idea depends on your use case; nowadays, you can almost certainly make ownership and lifetime semantics much clearer by using one of the smart-pointer types instead — even if it's just a std::weak_ptr.
Anyway, speaking more generally.
Are pointers "always" bad? No, of course not. I'd almost be tempted to say that managing dynamic memory yourself is "always" bad, but I won't make a generalisation.
Should you avoid them? Yes.
The difference is that the latter is a guideline to steer you away from manual memory management, and the former is an attempted prohibition.
No, using pointers in C++ is not bad at all, and I see this anti-advice over and over again. What is bad is managing pointers by yourself, unless you are creating a pointer-managing low-level entity.
Again, I shall make a very clear distinction. Using pointers is good. Very few real C++ programs can do without USING pointers. Managing pointers is bad, unless you are working on pointer manager.
A pointer can be nullptr whereas a reference must always be bound to something (and cannot be subsequently re-bound to something else).
That's the chief distinction and the primary consideration for your design choice.
Memory management of pointers can be delegated to std::shared_ptr and std::unique_ptr as appropriate.
well, I never had the need to 2 classes to have reciprocal reference and for good reasons, how do you know how to test those classes? If later you need to change something in the way the 2 classes communicates you will probably have to change code in both classes). You can workaround in many ways:
You may need in reality just 1 class ( you have broken into much classes)
You can register a Observer for a class (using a 3rd class, in that case you will end up with a pointer, but at least the 2 classes are less coupled and it is easier test them).
You can think (maybe) to a new interface that require only 1 class to call methods on the other class
You could pass a lambda (or a functor if you do not have C++11) into one of the methods of the class removing the need to a back reference
You could pass a reference of the class inside a method.
Maybe you have to few classes and in reality you need a third class than communicates with both classes.
It is possible you need a Visitor (maybe you really need multiple dispatch)
Some of the workarounds above need pointers, some not. To you the choice ;)
NOTE: However what you are doing is perfectly fine to me (I see you do some trickery only in constructors, but probably you have more omitted code, in wich case that can cause troubles to you). In my case I "register" one class into another, then after the constructor called I have only one class calling the other and not viceversa.
First of all whenever you have a circular dependency in your design think about it twice and make sure it's the way to go. Try to use the Dependency inversion principle in order to analyze and fix your dependencies.
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
Pointers are a powerful programming tool. Like any other feature in the C++ (or in any programming language in general) they have to be used when they are the right tool. In C++ additionally you have access to references which are similar to pointers in usage but with a better syntax. Additionally they can't be null. Thus they always reference a valid object.
So use pointers when you ever need to but try to avoid using raw pointers and prefer a smart pointer as alternative whenever possible. This will protect you against some trivial memory leak problems but you still have to pay attention to your object life-cycle and for each dynamically allocated object you should know clearly who create it and when/whom will release the memory allocated for the object.
Pointers (and references) are very useful in general because they could be used to pass parameters to a method by reference so you avoid passing heavy objects by value in the stack. Imagine the case for example that you have a very big array of heavy objects (which copy/= operator is time consuming) and you would like to sort these objects. One simple method is to use pointers to these objects so instead of moving the whole object during the sorting operation you just move the pointers which are very lightweight data type (size of machine address basically).
I am am wondering how to create properly properties in C++. In Objective C, I use "#property" (in general with the (nonatomic, retain) attributes).
What is the proper way in C++ ?
Thanks !!
As Seva said, there are no properties in that kind of sense in C++. What you could do: write a class with a boost::share_ptr member variable, and optionally write getter and setter for that member. But that isn't even really necessary, although maybe deemed good behaviour.
typedef boost::shared_ptr<std::string> StringPtrT;
class A {
public:
void setStringProperty(StringPtrT s) { this->string_property = s; }
StringPtrT getStringProperty() const { return this->string_property; }
protected:
StringPtrT string_property;
}
The shared pointer will deal with the sharing and reference counting, basically simulating some kind of "retain" behaviour. IIRC boost shared_ptr types are always atomic, when it comes to updateing the reference counts. However, access to the object itself (de-referencing the pointer) will be non-atomic. You will have to deal with that yourself, if needed.
#Ame's code is correct, but there's no particular requirement to use shared_ptr here. I am very torn on the use of shared_ptr broadly. It can be useful, but introduces a lot of subtle complexity in my experience. It is not the traditional C++ approach. C++ often prefers strong object ownership rather than shared ownership (which is the common model in ObjC). If you do use shared_ptr, it's built-in for Cocoa platforms, so you don't need boost. You may want to read Wrapping C++ – Take 2, Part 2 to get a sense of some of the complexities around shared_ptr (it's a little dated, and some of it is not applicable to ARC code).
That said, #Ame's approach is essentially correct. But you typically would use copying for simple properties rather than shared_ptr. (This is particularly true for strings, which you also copy in most ObjC code.) For someone looking for a style guide, I typically recommend Google's. It's not perfect, but it's very well considered, and it's good to start with something that at least is known to work for a lot of people before inventing your own. (EDIT: See #Matthieu M.'s comment below for a dissenting opinion.)
class MyClass {
public:
...
int num_entries() const { return num_entries_; }
void set_num_entries(int num_entries) { num_entries_ = num_entries; }
private:
int num_entries_;
};
Note the private: is correct here. I disagree with #Ame's use of protected:. Just like ObjC, you should use accessors even inside of classes, and definitely you should use them in subclasses. Allowing subclasses to directly access ivars is fragile. It requires subclasses to have special knowledge of their superclass.
For string properties and other simple or immutable objects, you should generally use the copy constructor rather than anything like shared_ptr. For more complex, mutable objects, C++ typically encourages strong object ownership rather than shared ownership. So there should (in general) be some one object responsible for creating, managing, and destroying that other complex object. Everyone else should just get references from the object's owner. They should never create or destroy the object themselves.
It's not that shared or strict ownership is better IMO. It's just that shared ownership is the ObjC way and all code works that way (and it is extremely elegant in that). Strict ownership is more the C++ way (as much as C++ can be said to have "a way") and trying to shoehorn shared ownership into it is often fragile.
I'm creating a class that will be part of a DAG. The constructor will take pointers to other instances and use them to initialize a dependency list.
After the dependency list is initialized, it can only ever be shortened - the instance can never be added as a dependency of itself or any of its children.
::std::shared_ptr is a natural for handling this. Reference counts were made for handling DAGs.
Unfortunately, the dependencies need to know their dependents - when a dependency is updated, it needs to tell all of its dependents.
This creates a trivial cycle that can be broken with ::std::weak_ptr. The dependencies can just forget about dependents that go away.
But I cannot find a way for a dependent to create a ::std::weak_ptr to itself while it's being constructed.
This does not work:
object::object(shared_ptr<object> dependency)
{
weak_ptr<object> me = shared_from_this();
dependency->add_dependent(me);
dependencies_.push_back(dependency);
}
That code results in the destructor being called before the constructor exits.
Is there a good way to handle this problem? I'm perfectly happy with a C++11-only solution.
Instead of a constructor, use a function to build the nodes of your graph.
std::shared_ptr<Node> mk_node(std::vector<std::shared_ptr<Node>> const &dependencies)
{
std::shared_ptr<Node> np(new Node(dependencies));
for (size_t i=0; i<dependencies.size(); i++)
dependencies[i].add_dependent(np); // makes a weak_ptr copy of np
return np;
}
If you make this a static member function or a friend of your Node class, you can make the actual constructor private.
Basically, you can't. You need a shared_ptr or weak_ptr to make a weak_ptr and obviously self can only be aware of of its own shared_ptr only in form of weak_ptr (otherwise there's no point in counting references). And, of course, there could be no self-shared_ptr when the object isn't yet constructed.
You can't.
The best I've come up with is to make the constructor private and have a public factory function that returns a shared_ptr to a new object; the factory function can then call a private method on the object post-construction that initialises the weak_ptr.
I'm understanding your question as conceptually related to garbage collection issues.
GC is a non-modular feature: it deals with some global property of the program (more precisely, being a live data is a global, non-modular, property inside a program - there are situations where you cannot deal with that in a modular & compositional way.). AFAIK, STL or C++ standard libraries does not help much for global program features.
A possible answer might be to use (or implement yourself) a garbage collector; Boehm's GC could be useful to you, if you are able to use it in your entire program.
And you could also use GC algorithms (even copying generational ones) to deal with your issue.
Unfortunately, the dependencies need to know their dependents. This is because when a dependency is updated, it needs to tell all of its dependents. And there is a trivial cycle. Fortunately, this cycle can be broken with ::std::weak_ptr. The dependencies can just forget about dependents that go away.
It sounds like a dependency can't reference a dependent unless the dependent exists. (E.g. if the dependent is destroyed, the dependency is destroyed too -- that's what a DAG is after all)
If that's the case, you can just hand out plain pointers (in this case, this). You're never going to need to check inside the dependency if the dependent is alive, because if the dependent died then the dependency should have also died.
Just because the object is owned by a shared_ptr doesn't mean that all pointers to it themselves must be shared_ptrs or weak_ptrs - just that you have to define clear semantics as to when the pointers become invalidated.
It sounds to me like you're trying to conflate to somewhat different items: a single object (a node in the DAG), and managing a collection of those objects.
class DAG {
class node {
std::vector<std::weak_ptr<node> > dependents;
public:
node(std::vector<weak_ptr<node> > d) : dependents(d) {}
};
weak_ptr<node> root;
};
Now, it may be true that DAG will only ever hold a weak_ptr<node> rather than dealing with an instance of a node directly. To the node itself, however, this is more or less irrelevant. It needs to maintain whatever key/data/etc., it contains, along with its own list of dependents.
At the same time, by nesting it inside of DAG (especially if we make the class definition of node private to DAG), we can minimize access to node, so very little other code has to be concerned with anything about a node. Depending on the situation, you might also want to do things like deleting some (most?) of the functions in node that the compiler will generate by default (e.g., default ctor, copy ctor, assignment operator).
This has been driving me nuts as well.
I considered adopting the policy of using pointers to break cycles... But I'm really not found of this because I really like how clear the intent of the weak_ptr is when you see it in your code (you know it's there to break cycles).
Right now I'm leaning toward writing my own weak_ptr class.
Maybe this will help:
inherit from enable_shared_from_this which basically holds a weak_ptr.
This will allow you to use this->shared_from_this();
shared_ptr's know to look if the class inherits from the class and use the classes weak_ptr when pointing to the object (prevents 2 shared pointers from counting references differently)
More about it: cppreference
I've been evaluating various smart pointer implementations (wow, there are a LOT out there) and it seems to me that most of them can be categorized into two broad classifications:
1) This category uses inheritance on the objects referenced so that they have reference counts and usually up() and down() (or their equivalents) implemented. IE, to use the smart pointer, the objects you're pointing at must inherit from some class the ref implementation provides.
2) This category uses a secondary object to hold the reference counts. For example, instead of pointing the smart pointer right at an object, it actually points at this meta data object... Who has a reference count and up() and down() implementations (and who usually provides a mechanism for the pointer to get at the actual object being pointed to, so that the smart pointer can properly implement operator ->()).
Now, 1 has the downside that it forces all of the objects you'd like to reference count to inherit from a common ancestor, and this means that you cannot use this to reference count objects that you don't have control over the source code to.
2 has the problem that since the count is stored in another object, if you ever have a situation that a pointer to an existing reference counted object is being converted into a reference, you probably have a bug (I.E., since the count is not in the actual object, there is no way for the new reference to get the count... ref to ref copy construction or assignment is fine, because they can share the count object, but if you ever have to convert from a pointer, you're totally hosed)...
Now, as I understand it, boost::shared_pointer uses mechanism 2, or something like it... That said, I can't quite make up my mind which is worse! I have only ever used mechanism 1, in production code... Does anyone have experience with both styles? Or perhaps there is another way thats better than both of these?
"What is the best way to implement smart pointers in C++"
Don't! Use an existing, well tested smart pointer, such as boost::shared_ptr or std::tr1::shared_ptr (std::unique_ptr and std::shared_ptr with C++ 11)
If you have to, then remember to:
use safe-bool idiom
provide an operator->
provide the strong exception guarantee
document the exception requirements your class makes on the deleter
use copy-modify-swap where possible to implement the strong exception guarantee
document whether you handle multithreading correctly
write extensive unit tests
implement conversion-to-base in such a way that it will delete on the derived pointer type (policied smart pointers / dynamic deleter smart pointers)
support getting access to raw pointer
consider cost/benifit of providing weak pointers to break cycles
provide appropriate casting operators for your smart pointers
make your constructor templated to handle constructing base pointer from derived.
And don't forget anything I may have forgotten in the above incomplete list.
Just to supply a different view to the ubiquitous Boost answer (even though it is the right answer for many uses), take a look at Loki's implementation of smart pointers. For a discourse on the design philosophy, the original creator of Loki wrote the book Modern C++ Design.
I've been using boost::shared_ptr for several years now and while you are right about the downside (no assignment via pointer possible), I think it was definitely worth it because of the huge amount of pointer-related bugs it saved me from.
In my homebrew game engine I've replaced normal pointers with shared_ptr as much as possible. The performance hit this causes is actually not so bad if you are calling most functions by reference so that the compiler does not have to create too many temporary shared_ptr instances.
Boost also has an intrusive pointer (like solution 1), that doesn't require inheriting from anything. It does require changing the pointer to class to store the reference count and provide appropriate member functions. I've used this in cases where memory efficiency was important, and didn't want the overhead of another object for each shared pointer used.
Example:
class Event {
public:
typedef boost::intrusive_ptr<Event> Ptr;
void addRef();
unsigned release();
\\ ...
private:
unsigned fRefCount;
};
inline void Event::addRef()
{
fRefCount++;
}
inline unsigned Event::release(){
fRefCount--;
return fRefCount;
}
inline void intrusive_ptr_add_ref(Event* e)
{
e->addRef();
}
inline void intrusive_ptr_release(Event* e)
{
if (e->release() == 0)
delete e;
}
The Ptr typedef is used so that I can easily switcth between boost::shared_ptr<> and boost::intrusive_ptr<> without changing any client code
If you stick with the ones that are in the standard library you will be fine.
Though there are a few other types than the ones you specified.
Shared: Where the ownership is shared between multiple objects
Owned: Where one object owns the object but transfer is allowed.
Unmovable: Where one object owns the object and it can not be transferred.
The standard library has:
std::auto_ptr
Boost has a couple more than have been adapted by tr1 (next version of the standard)
std::tr1::shared_ptr
std::tr1::weak_ptr
And those still in boost (which in relatively is a must have anyway) that hopefully make it into tr2.
boost::scoped_ptr
boost::scoped_array
boost::shared_array
boost::intrusive_ptr
See:
Smart Pointers: Or who owns you baby?
It seems to me this question is kind of like asking "Which is the best sort algorithm?" There is no one answer, it depends on your circumstances.
For my own purposes, I'm using your type 1. I don't have access to the TR1 library. I do have complete control over all the classes I need to have shared pointers to. The additional memory and time efficiency of type 1 might be pretty slight, but memory usage and speed are big issues for my code, so type 1 was a slam dunk.
On the other hand, for anyone who can use TR1, I'd think the type 2 std::tr1::shared_ptr class would be a sensible default choice, to be used whenever there isn't some pressing reason not to use it.
The problem with 2 can be worked around. Boost offers boost::shared_from_this for this same reason. In practice, it's not a big problem.
But the reason they went with your option #2 is that it can be used in all cases. Relying on inheritance isn't always an option, and then you're left with a smart pointer you can't use for half your code.
I'd have to say #2 is best, simply because it can be used in any circumstances.
Our project uses smart pointers extensively. In the beginning there was uncertainty about which pointer to use, and so one of the main authors chose an intrusive pointer in his module and the other a non-intrusive version.
In general, the differences between the two pointer types were not significant. The only exception being that early versions of our non-intrusive pointer implicitly converted from a raw pointer and this can easily lead to memory problems if the pointers are used incorrectly:
void doSomething (NIPtr<int> const &);
void foo () {
NIPtr<int> i = new int;
int & j = *i;
doSomething (&j); // Ooops - owned by two pointers! :(
}
A while ago, some refactoring resulted in some parts of the code being merged, and so a choice had to be made about which pointer type to use. The non-intrusive pointer now had the converting constructor declared as explicit and so it was decided to go with the intrusive pointer to save on the amount of code change that was required.
To our great surprise one thing we did notice was that we had an immediate performance improvement by using the intrusive pointer. We did not put much research into this, and just assumed that the difference was the cost of maintaining the count object. It is possible that other implementations of non-intrusive shared pointer have solved this problem by now.
What you are talking about are intrusive and non-intrusive smart pointers. Boost has both. boost::intrusive_ptr calls a function to decrease and increase the reference count of your object, everytime it needs to change the reference count. It's not calling member functions, but free functions. So it allows managing objects without the need to change the definition of their types. And as you say, boost::shared_ptr is non-intrusive, your category 2.
I have an answer explaining intrusive_ptr: Making shared_ptr not use delete. In short, you use it if you have an object that has already reference counting, or need (as you explain) an object that is already referenced to be owned by an intrusive_ptr.
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?
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.
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.
I've recently been bitten by the DI bug. I think it solves a lot of complexity problems, especially the automated part. I've written a prototype which lets you use DI in a pretty C++ way, or at least I think so. You can take a look at the code example here: http://codepad.org/GpOujZ79
The things that are obviously missing: no scoping, no binding of interface to implementation. The latter is pretty easy to solve, the former, I've no idea.
I'd be grateful if anyone here has an opinion on the code.
Use RAII.
Handing a raw pointer to someone is the same as handing them ownership. If that's not what you want to do, you should give them some kind of facade that also knows how to clean up the object in question.
shared_ptr<> can do this; the second argument of its constructor can be a function object that knows how to delete the object.
In C++, normally, when you done things right, you don't need to write destructors at all in most cases. You should use smart pointers to delete things automatically. I think, builder don't looks like the owner of the ClassA and ClassB instances. If you don't like to use smart pointers, you should think about objects life time and their owners.
Things get complicated if you don't settle on the question of ownership once and for all. You will simply have to decide in your implementation if it's possible that dependencies live longer than the objects they are injected into.
Personally I'd say no: the object into which the dependency is injected will clean up afterwards. Trying to do it through the builder means that the builder will have to live longer than both the dependency and the object into which it is injected. This causes more problems than it solves, in my opinion, because the builder does not serve any more useful purpose after the construction with the dependency injection has been completed.
Based on my own experience, it is best to have clear ownership rules. For small concrete objects, it is best to use direct copy to avoid cross dependency.
Sometimes cross dependency is unavoidable, and there is no clear ownership. For example, (m) A instances own (n) B instances, and certain B instances can be owned by multiple As. In this case, the best approach is to apply reference counting to B, in the way similar to COM reference counting. Any functions that take possession of B* must increase reference count first, and decrease it when releasing the possession.
I also avoid using boost::shared_ptr as it creates a new type (shared_ptr and B* become two distinct types). I found that it brings more headaches when I add methods.
You can also check the FFEAD Dependency Injection. It provides DI on the lines of Spring for JAVA and has a non-obtrusive way of dealing with things. It also has a lot of other important features like in-built AJAX Support,Reflection,Serialization,C++ Interpreter,Business Components For C++,ORM,Messaging,Web-Services,Thread-Pools and an Application Server that supports all these features.