Recently, I have been using a lot of different smart raise pointers, as well as regular pointers. I noticed that as you develop, as a rule, you understand that you need to switch the types of pointers and the memory management mechanism, because you are missing some kind of circular dependency or some kind of small annoying thing. When this happens, and you change your pointer type, you need to either go or change a whole bunch of method signatures to take a new pointer type, or you need to convert pointer types at each call site. You also have a problem if you have the same function, but you want it to use several types of pointers.
I wonder if there is already a general way to deal with it, i.e. write methods that are agnostic like the type of pointer you pass to it?
Obviously, I see several ways to do this: you need to write overloaded methods for each type of pointer, but this quickly becomes a problem. Another is to use a template style solution with some type of output, but this will cause some significant bloat in the compiled code and probably start throwing strange errors of an unsolvable template.
My idea - to write a novel class of any_ptr<T>constructors conversion of all major types of signs, such as T*, shared_ptr<T>, auto_ptr<T>, scoped_ptr<T>, perhaps weak_ptr<T>, and then use that print statements *and ->. Thus, it can be used in any function that does not return a pointer outside the function and can be called with any combination of common pointer types.
: ? , , , , any_ptr, , ? , .
1
, , .
- (@shoosh). , raw-, , shared_ptr, , ptr.get() , , weak_ptr, x.lock(). Get(). , , , , . T & * x, .
, , - .
- smart_ptr: , , ( boost::shared_ptr<T> T*).
any_ptr (, ) , ( -, , , ). , * → T * ( T*()). , any_ptr , T*. , raw ptr ( @Alexandre_C ). , " ", @Matthieu_M.
- . , , .
. , , , raw ptr (T *) , , smart_ptr . , , - , , , (, , , ), , .
, unmanaged_ptr any_ptr. . .
EDIT 2
, , . dumb_ptr.
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;
};
T *, T *. (=) , -, . .
void some_fn(dumb_ptr<A> ptr) {
B = ptr->b;
A a = *ptr;
A* raw = ptr;
ptr==raw;
ptr+1;
}
, . , T*. (.get,.lock) . , , .
, , ?