New universal pointer any_ptr (now dumb_ptr) to make code more reusable among smart pointers

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) . , , .

, , ?

+3
5

, . , , . @Alexandre C. , .

0

any_ptr , * ->. , , . , , , T*, .get() whatnot .

+2

-, :

virtual void MyMethod(MyClass* ptr)
{
    ptr->doSomething();
}

do

MyObj->MyMethod(mySmartPtr.get());

?

:

virtual void MyMethod(const MyClass& ptr)
{
    ptr->doSomething();
}

do

MyObj->MyMethod(*mySmartPointer);

, ( std::weak_ptr).

: std::unique_ptr, std::shared_ptr std::weak_ptr .

. .

, , , , . , shared_ptr const, .

typedefs:

struct MyClass
{
    typedef std::shared_ptr<MyClass> Handle;
    static Handle CreateHandle(...);

    ...

private:
    Handle internalHandle;
    void setHandle(const MyClass::Handle& h);
};

do

void MyClass::setHandle(const MyClass::Handle& h)
{
    this->internalHandle = h;
}
+1

, .

any_ptr? unique_ptr/scoped_ptr, . shared_ptr weak_ptr, .

(, ) ...


. ( ), , .

, , , , ( , ), :

  • void foo(T* ptr);, shared_ptr<T> p; foo(p.get());
  • void foo(T& ptr);, foo(*p);

:

: , . , , ... , .

+1

, , , , . , , .

, , .. , , ?

.

The smart pointer should be present in the function signatures only in case of transfer of ownership of the object. If the function does not accept ownership of the object, it must accept it with a simple pointer or reference. Only functions that should own an object or extend its life should accept it with a smart pointer.

+1
source

All Articles