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.
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).
From here: http://www.oodesign.com/proxy-pattern.html
Applicability & Examples
The Proxy design pattern is applicable when there is a need to control
access to an Object, as well as when there is a need for a
sophisticated reference to an Object. Common Situations where the
proxy pattern is applicable are:
Virtual Proxies: delaying the creation and initialization of expensive
objects until needed, where the objects are created on demand (For
example creating the RealSubject object only when the doSomething
method is invoked).
Protection Proxies: where a proxy controls access to RealSubject
methods, by giving access to some objects while denying access to
others.
Smart References: providing a sophisticated access to certain objects
such as tracking the number of references to an object and denying
access if a certain number is reached, as well as loading an object
from database into memory on demand.
Well, can't Virtual Proxies be created by creating an individual function (other than the constructor) for a new object?
Can't Protection Proxies be created by simply making the function private, and letting only the derived classes get the accesses? OR through the friend class?
Can't Smart References be created by a static member variable which counts the number of objects created?
In which cases should the Proxy method be preferred on the access specifiers and inheritance?
What's the point that I am missing?
Your questions are a little bit abstract, and i'm not sure i can answer at all well, but here are my thoughts on each of them. Personally i dont agree that some of these things are the best designs for the job, but that isn't your question, and is a matter of opinion.
Virtual Proxies
I don't understand what you are trying to say here at all. The point of the pattern here is that you might have an object A that you know will take 100MB, and you don't know for sure that you will ever need to use this object.
To avoid allocating memory for this object until it is needed you create a dummy object B that implements the same interface as A, and if any of its methods are called B creates an instance of A, thus avoiding allocating memory until it is needed.
Protection Proxies
Here i think you have misunderstood the use of the pattern. The idea is to be able to dynamically control access to an object. For example you might want class A to be able to access class B's methods unless condition C is true. As i'm sure you can see this could not be achieved through the use of access specifiers.
Smart Referances
Here i think you misunderstand the need for smart pointers. As this is quite a complicated topic i will simply provide a link to a question about them: RAII and smart pointers in C++
If you have never programmed in a language like C where you manage your memory yourself then this might explain the confusion.
I hope this helps to answer some of your questions.
EDIT:
I didn't notice that this was tagged c++ so i assume you do in fact recognize the need to clean up dynamic memory. The single static reference count will only work if you only intend to ever have one instance of your object. If you create 2000 instances of an object, and then deleted 1999 of them none of them would have their memory freed until the last one left scope which is clearly not desirable (That is assuming you had kept track of the locations of all the allocated memory in order to be able to free it!).
EDIT 2:
Say you have a class as follows:
class A {
public:
static int refcount;
int* allocated_memory;
A() {
++refcount;
allocated_memory = new int[100000000];
}
~A() {
if(! --refcount) {
delete [] allocated_memory;
}
}
}
And some code that uses it:
int main() {
A problem_child; // After this line refcount == 1
while(true) {
A in_scope; // Here refcount == 2
} // We leave scope and refcount == 1.
// NOTE: in_scope.allocated_memory is not deleted
// and we now have no pointer to it. Leak!
return;
}
As you can see in the code refcount counts all references to all objects, and this results in a memory leak. I can explain further if you need, but this is really a seperate question in its own right.
I am no expert, but here are my thoughts on Virtual Proxies : If we control the initialization via a separate function say bool Create(); then the responsibility and control of Initialization lies with the client of the class. With virtual proxies , the goal is to retain creation control within the class, without client being aware of that.
Protection Proxies: The Subject being protected might have different kinds of clients, ones which need to get unprotected/unrestricted access to all Subject methods and the others which should be allowed access to a subset of methods hence need for Protection proxy.
A proxy is an object behaving as a different object to add some control/behavior. A smart pointer is a good example: it accesses the object as if you would use a raw pointer, but it also controls the lifetime of that object.
It's good to question whether there are alternatives to standard solutions to problems. Design Patterns represent solutions that have worked for many folks and have the advantage that there's a good chance that an experienced programmer coming to the code will recognize the pattern and so find maintaining the code easier. However, all designs represent trade-offs and patterns have costs. So you are right to challenge the use of patterns and consider alternatives.
In many cases design is not just about making code work, but considering how it is structured. Which piece of code "knows" what. You proposal for an alternative for Virtual Prozy moves (as fizzbuzz says) knowledge of creation from the proxy to the client - the client has to "know" to call Create() and so is aware of the life-cycle of the class. Whereas with the proxy he just makes an object that he treats as the worker, then invisibly creation happens when the proxy decides it makes sense. This refactoring of responsibility into the proxy is found to valuable, it allows us in the future to change those life-cycle rules without changing any clients.
Protection proxy: your proposal requires that clients have an inheritance relationship so that they can use protected methods. Generally speaking that couples client and worker too tightly, so we introduce a proxy.
Smart reference: no, a single static count is no good. You need to count references to individual instances.
If you carefully work through each case you will find there are merits to the design patterns. If you try to implement an alternative you start with some code that sems simpler that the design pattern and then discover that as you start to refactor and improve the code, removing deuplicationand so on you end up reinventing the design pattern - and that's a really nice outcome.
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.
I have a class that references a bunch of other classes. I want to be able to add these references incrementally (i.e. not all at the same time on the constructor), and I want to disallow the ability to delete the object underlying these references from my class, also I want to test for NULL-ness on these references so I know a particular reference has not been added. What is a good design to accomplish these requirements?
I agree with other comments that you should use boost::shared_ptr.
However if you don't want the class holding these references to part-control the lifetime of the objects it references you should consider using boost::weak_ptr to hold the references then turn this into a shared_ptr when you want to us it. This will allow the referenced objects to be deleted before your class, and you will always know if object has been deleted before using it.
It sounds like you might be trying to build a Service Locator.
As a side-comment: I would personally recommend not doing that, because it is going to make testing really, really painful if you ever want to do it. Constructor injection (Something that you are trying to avoid) will make testing much easier.
Shouldn't you use the refcounted class, so that your reference will be managed until your primary class get destroyed.
You are most likely looking for boost::shared_ptr.
Despite all the recommendations that you use boost:;shared_pointer, it is far from obvious from your post that it would be appropriate to do so, as the class appears to have no ownership semantics. An ordinary C++ pointer will do just fine here.
It is difficult at the end of the day to prevent deletion via smart pointer, as the
smart pointer must, in some form or other, provide access to the underlying dumb pointer, which of course can always be deleted. For some problems there is no technological solution, and in this case a code review is the best way to detect semantic errors in using the contained pointers.
The object you want to reference could be derived from with something like this. That would prevent you from deleting them.
class T
class NonDeletable : public T
{
private:
void operator delete(void*);
};
I've learned in College that you always have to free your unused Objects but not how you actually do it. For example structuring your code right and so on.
Are there any general rules on how to handle pointers in C++?
I'm currently not allowed to use boost. I have to stick to pure c++ because the framework I'm using forbids any use of generics.
I have worked with the embedded Symbian OS, which had an excellent system in place for this, based entirely on developer conventions.
Only one object will ever own a pointer. By default this is the creator.
Ownership can be passed on. To indicate passing of ownership, the object is passed as a pointer in the method signature (e.g. void Foo(Bar *zonk);).
The owner will decide when to delete the object.
To pass an object to a method just for use, the object is passed as a reference in the method signature (e.g. void Foo(Bat &zonk);).
Non-owner classes may store references (never pointers) to objects they are given only when they can be certain that the owner will not destroy it during use.
Basically, if a class simply uses something, it uses a reference. If a class owns something, it uses a pointer.
This worked beautifully and was a pleasure to use. Memory issues were very rare.
Rules:
Wherever possible, use a
smart pointer. Boost has some
good ones.
If you
can't use a smart pointer, null out
your pointer after deleting it.
Never work anywhere that won't let you use rule 1.
If someone disallows rule 1, remember that if you grab someone else's code, change the variable names and delete the copyright notices, no-one will ever notice. Unless it's a school project, where they actually check for that kind of shenanigans with quite sophisticated tools. See also, this question.
I would add another rule here:
Don't new/delete an object when an automatic object will do just fine.
We have found that programmers who are new to C++, or programmers coming over from languages like Java, seem to learn about new and then obsessively use it whenever they want to create any object, regardless of the context. This is especially pernicious when an object is created locally within a function purely to do something useful. Using new in this way can be detrimental to performance and can make it all too easy to introduce silly memory leaks when the corresponding delete is forgotten. Yes, smart pointers can help with the latter but it won't solve the performance issues (assuming that new/delete or an equivalent is used behind the scenes). Interestingly (well, maybe), we have found that delete often tends to be more expensive than new when using Visual C++.
Some of this confusion also comes from the fact that functions they call might take pointers, or even smart pointers, as arguments (when references would perhaps be better/clearer). This makes them think that they need to "create" a pointer (a lot of people seem to think that this is what new does) to be able to pass a pointer to a function. Clearly, this requires some rules about how APIs are written to make calling conventions as unambiguous as possible, which are reinforced with clear comments supplied with the function prototype.
In the general case (resource management, where resource is not necessarily memory), you need to be familiar with the RAII pattern. This is one of the most important pieces of information for C++ developers.
In general, avoid allocating from the heap unless you have to. If you have to, use reference counting for objects that are long-lived and need to be shared between diverse parts of your code.
Sometimes you need to allocate objects dynamically, but they will only be used within a certain span of time. For example, in a previous project I needed to create a complex in-memory representation of a database schema -- basically a complex cyclic graph of objects. However, the graph was only needed for the duration of a database connection, after which all the nodes could be freed in one shot. In this kind of scenario, a good pattern to use is something I call the "local GC idiom." I'm not sure if it has an "official" name, as it's something I've only seen in my own code, and in Cocoa (see NSAutoreleasePool in Apple's Cocoa reference).
In a nutshell, you create a "collector" object that keeps pointers to the temporary objects that you allocate using new. It is usually tied to some scope in your program, either a static scope (e.g. -- as a stack-allocated object that implements the RAII idiom) or a dynamic one (e.g. -- tied to the lifetime of a database connection, as in my previous project). When the "collector" object is freed, its destructor frees all of the objects that it points to.
Also, like DrPizza I think the restriction to not use templates is too harsh. However, having done a lot of development on ancient versions of Solaris, AIX, and HP-UX (just recently - yes, these platforms are still alive in the Fortune 50), I can tell you that if you really care about portability, you should use templates as little as possible. Using them for containers and smart pointers ought to be ok, though (it worked for me). Without templates the technique I described is more painful to implement. It would require that all objects managed by the "collector" derive from a common base class.
G'day,
I'd suggest reading the relevant sections of "Effective C++" by Scott Meyers. Easy to read and he covers some interesting gotchas to trap the unwary.
I'm also intrigued by the lack of templates. So no STL or Boost. Wow.
BTW Getting people to agree on conventions is an excellent idea. As is getting everyone to agree on conventions for OOD. BTW The latest edition of Effective C++ doesn't have the excellent chapter about OOD conventions that the first edition had which is a pity, e.g. conventions such as public virtual inheritance always models an "isa" relationship.
Rob
When you have to use manage memory
manually, make sure you call delete
in the same
scope/function/class/module, which
ever applies first, e.g.:
Let the caller of a function allocate the memory that is filled by it,
do not return new'ed pointers.
Always call delete in the same exe/dll as you called new in, because otherwise you may have problems with heap corruptions (different incompatible runtime libraries).
you could derive everything from some base class that implement smart pointer like functionality (using ref()/unref() methods and a counter.
All points highlighted by #Timbo are important when designing that base class.