In my new project I wish to (mostly for to see how it will work out) completely ban raw pointers from my code.
My first approach was to let all classes inherit from this simple class:
template
class Base
{
public:
typedef std::shared_ptr ptr;
};
And simple use class::ptr wherever I need a pointer.
This approach seemed suitable until I realized sometimes my objects wish to pass the 'this' pointer to other objects. Letting my objects just wrap it inside a shared_ptr won't do since then there could be two owners for the same pointer. I assume this is bad.
My next idea was to change the 'Base' class to implement reference counting itself, thus every instance of classes that inherits from 'Base' can only have one count.
Is this a good solution, are there any better and can boost and/or stl already solve this problem for me?
You may want to take a look at enable_shared_from_this.
On another note, when using shared_ptr, you need to be aware of the possibility of circular references. To avoid this, you can use weak_ptr. This means you will need some way to distinguish between the two of them, so simply having a typedef class::ptr may not suffice.
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'm having trouble getting things organized properly with smart pointers. Almost to the point that I feel compelled to go back to using normal pointers.
I would like to make it easy to use smart pointers throughout the program without having to type shared_ptr<...> every time. One solution I think of right away is to make a template class and add a typedef sptr to it so I can do class Derived : public Object < Derived > .. and then use Derived::sptr = ... But this obviously is horrible because it does not work with another class that is then derived from Derived object.
And even doing typedef shared_ptr<..> MyObjectPtr is horrible because then it needs to be done for each kind of smart pointer for consistency's sake, or at least for unique_ptr and shared_ptr.
So what's the standard way people use smart pointers? Because frankly I'm starting to see it as being too much hassle to use them. :/
So what's the standard way people use smart pointers?
Rarely. The fact that you find it a hassle to use them is a sign that you over-use pointers. Try to refactor your code to make pointers the exception, not the rule. shared_ptr in particular has its niche, but it’s a small one: namely, when you genuinely have to share ownership of a resource between several objects. This is a rare situation.
Because frankly I'm starting to see it as being too much hassle to use them. :/
Agreed. That’s the main reason not to use pointers.
There are more ways to avoid pointers. In particular, shared_ptr really only needs to spelled out when you actually need to pass ownership. In functions which don’t deal with ownership, you wouldn’t pass a shared_ptr, or a raw pointer; you would pass a reference, and dereference the pointer upon calling the function.
And inside functions you almost never need to spell out the type; for instance, you can (and should) simply say auto x = …; instead of shared_ptr<Class> x = …; to initialise variables.
In summary, you should only need to spell out shared_ptr in very few places in your code.
I have a lot of code that creates objects dynamically. So using pointers is necessary because the number of objects is not known from the start. An object is created in one subsystem, then stored in another, then passed for further processing to the subsystem that created it. So that I guess means using shared_ptr. Good design? I don't know, but it seems most logical to ask subsystem to create a concrete object that it owns, return a pointer to an interface for that object and then pass it for further processing to another piece of code that will interact with the object through it's abstract interface.
I could return unique_ptr from factory method. But then I would run into trouble if I need to pass the object for processing multiple times. Because I would still need to know about the object after I pass it to another method and unique_ptr would mean that I lose track of the object after doing move(). Since I need to have at least two references to the object this means using shared_ptr.
I heard somewhere that most commonly used smart pointer is unique_ptr. Certainly not so in my application. I end up with using shared_ptr mush more often. Is this a sign of bad design then?
First: is it boost::noncopyable or booster::noncopyable. I have seen both in different places.
Why would one want to make a class noncopyable? Can you give some sample use cases?
I find it useful whenever you have a class that has a pointer as a member variable which that class owns (ie is responsible for destroying). Unless you're using shared_ptr<> or some other reference-counted smart pointer, you can't safely copy or assign the class, because in the destructor you will want to delete the pointer. However, you don't know if a copy of the class has been taken and hence you'll get either a double-delete or access violation from dereferencing a freed pointer.
If you inherit from noncopyable then it has two benefits:
It prevents the class from being copied or assigned
It makes the intention clear from looking at the class definition, ie self-documenting code
eg
class MyClass : boost::noncopyable
{
...
};
The right one in the case of boost is boost::noncopyable.
It is used to prevent copying of objects like the name tells. It makes sense where copying leads to a very difficult to handle situation. An example is a class wrapping the concept of file handle or network connection like stated in the documentation. The problems arise with freeing/closing the resource or file. If you have many copies of them how would you handle it. You could use some reference counting but it is difficult to handle correctly if you unwrap the handles at some places...
Personally I find its most clear and useful usage in implementing a singleton pattern, where you really want to have only one instance, that in this case you obviously do not want to be copyable. Singletons ensure only one instance of a class can be created for holding some global resources for example a system configuration.
I'd like to manage a bunch of objects of classes derived from a shared interface class in a common container.
To illustrate the problem, let's say I'm building a game which will contain different actors. Let's call the interface IActor and derive Enemy and Civilian from it.
Now, the idea is to have my game main loop be able to do this:
// somewhere during init
std::vector<IActor> ActorList;
Enemy EvilGuy;
Civilian CoolGuy;
ActorList.push_back(EvilGuy);
ActorList.push_back(CoolGuy);
and
// main loop
while(!done) {
BOOST_FOREACH(IActor CurrentActor, ActorList) {
CurrentActor.Update();
CurrentActor.Draw();
}
}
... or something along those lines. This example obviously won't work but that is pretty much the reason I'm asking here.
I'd like to know: What would be the best, safest, highest-level way to manage those objects in a common heterogeneous container? I know about a variety of approaches (Boost::Any, void*, handler class with boost::shared_ptr, Boost.Pointer Container, dynamic_cast) but I can't decide which would be the way to go here.
Also I'd like to emphasize that I want to stay away as far as possible from manual memory management or nested pointers.
Help much appreciated :).
To solve the problem which you have mentioned, although you are going in right direction, but you are doing it the wrong way. This is what you would need to do
Define a base class (which you are already doing) with virtual functions which would be overridden by derived classes Enemy and Civilian in your case.
You need to choose a proper container with will store your object. You have taken a std::vector<IActor> which is not a good choice because
Firstly when you are adding objects to the vector it is leading to object slicing. This means that only the IActor part of Enemy or Civilian is being stored instead of the whole object.
Secondly you need to call functions depending on the type of the object (virtual functions), which can only happen if you use pointers.
Both of the reason above point to the fact that you need to use a container which can contain pointers, something like std::vector<IActor*> . But a better choice would be to use container of smart pointers which will save you from memory management headaches. You can use any of the smart pointers depending upon your need (but not auto_ptr)
This is what your code would look like
// somewhere during init
std::vector<some_smart_ptr<IActor> > ActorList;
ActorList.push_back(some_smart_ptr(new Enemy()));
ActorList.push_back(some_smart_ptr(new Civilian()));
and
// main loop
while(!done)
{
BOOST_FOREACH(some_smart_ptr<IActor> CurrentActor, ActorList)
{
CurrentActor->Update();
CurrentActor->Draw();
}
}
Which is pretty much similar to your original code except for smart pointers part
My instant reaction is that you should store smart pointers in the container, and make sure the base class defines enough (pure) virtual methods that you never need to dynamic_cast back to the derived class.
As you have guessed you need to store the objects as pointers.
I prefer to use the boost pointer containers (rather than a normal container of smart pointers).
The reason for this is the boost ptr container access the objects as if they were objects (returning references) rather than pointers. This makes it easier to use standard functors and algorithms on the containers.
The disadvantage of smart pointers is that you are sharing ownership.
This is not what you really want. You want ownership to be in a single place (in this case the container).
boost::ptr_vector<IActor> ActorList;
ActorList.push_back(new Enemy());
ActorList.push_back(new Civilian());
and
std::for_each(ActorList.begin(),
ActorList.end(),
std::mem_fun_ref(&IActor::updateDraw));
If you want the container to exclusively own the elements in it, use a Boost pointer container: they're designed for that job. Otherwise, use a container of shared_ptr<IActor> (and of course use them properly, meaning that everyone who needs to share ownership uses shared_ptr).
In both cases, make sure that the destructor of IActor is virtual.
void* requires you to do manual memory management, so that's out. Boost.Any is overkill when the types are related by inheritance - standard polymorphism does the job.
Whether you need dynamic_cast or not is an orthogonal issue - if the users of the container only need the IActor interface, and you either (a) make all the functions of the interface virtual, or else (b) use the non-virtual interface idiom, then you don't need dynamic_cast. If the users of the container know that some of the IActor objects are "really" civilians, and want to make use of things which are in the Civilian interface but not IActor, then you will need casts (or a redesign).
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*);
};