STOP READING NOW!!
Seriously this post will make no sense to you, do something you will enjoy like going swimming. For those who are programmers this may interest you.
I have been using a lot of different boost smart pointers lately, as well as normal pointers. I have noticed that as you develop you tend to realise that you have to switch pointer types and memory management mechanism because you overlooks some circular dependency or some othe small annoying thing. When this happens and you change your pointer type you have to either go and change a whole bunch of you method signatures to take the new pointer type, or at each call site you have to convert between pointer types. You also have a problem if you have the same function but want it to take multiple pointer types.
I was wondering if there already existed a generic way to deal with this, i.e. write methods that are agnostic of the pointer type you pass to it?
You could also overload your methods for different pointer types, but thats a huge waste of time and makes the more code difficult to read. Another way is to use a template style solution with some type inference, but this would cause some significant bloat in the compiled code and is likely to start throwing strange unsolvable template errors.
My idea was to write a new class any_ptr<T> with conversion constructors from all the major pointer types, say, T*, shared_ptr<T>, auto_ptr<T>, scoped_ptr<T> and weak_ptr<T>and then have it expose the * and -> operators. In this way it could be used in any function that does not return the pointer outside of the function and could be called with any combination of common pointer types.
The class ended up being really simple, here it is:
template<typename T>
class dumb_ptr {
public:
dumb_ptr(const dumb_ptr<T> & dm_ptr) : raw_ptr(dm_ptr.raw_ptr) { }
dumb_ptr(T* raw_ptr) : raw_ptr(raw_ptr) { }
dumb_ptr(const boost::shared_ptr<T> & sh_ptr) : raw_ptr(sh_ptr.get()) { }
dumb_ptr(const boost::weak_ptr<T> & wk_ptr) : raw_ptr(wk_ptr.lock().get()) { }
dumb_ptr(const boost::scoped_ptr<T> & sc_ptr) : raw_ptr(sc_ptr.get()) { }
dumb_ptr(const std::auto_ptr<T> & au_ptr) : raw_ptr(au_ptr.get()) { }
T& operator*() { return *raw_ptr; }
T * operator->() { return raw_ptr; }
operator T*() { return raw_ptr; }
private:
dumb_ptr() { }
dumb_ptr<T> operator=(const dumb_ptr<T> & x) { }
T* raw_ptr;
};
void some_fn(dumb_ptr<A> ptr) {
B = ptr->b;
A a = *ptr;
A* raw = ptr;
ptr==raw;
ptr+1;
}
So I think this is a pretty neat solution. The idea and most of the content for this post come from a Stackoverflow question I asked, where I presented this idea and asked if anyone saw any major problems with it. The answering parties didn't think much of it, but I think they missed the point (No offence intended) . The point is that it should be less of a hassle to program, even in languages like C++.
Well that's it, I hope someone finds it useful