Smart Pointer Implementation - Dynamic Distribution Using Templates

I am in writing a smart pointer countedptr and I came across speed. The main function of countedptr is to work like any other smart pointer, and also count how many pointers point to a single object. So far, the code is:

[SOLVED]

#include "std_lib_facilities.h"

template <class T>
class counted_ptr{
private:
    T* pointer;
    int* count;

public:
    counted_ptr(T* p = 0, int* c = new int(1)) : pointer(p), count(c) {}    // default constructor
    explicit counted_ptr(const counted_ptr& p) : pointer(p.pointer), count(p.count) { ++*count; } // copy constructor
    ~counted_ptr() { --*count; delete pointer; }

    counted_ptr& operator=(const counted_ptr& p)
    {
        pointer = p.pointer;
        count = p.count;
        ++*count;
        return *this;
    }
    T* operator->() const{ return pointer; }
    T& operator*() const { return *pointer; }

    int Get_count() const { return *count; }
};


int main()
{
    counted_ptr<double> one;
    counted_ptr<double>two(one);
    int a = one.Get_count();
    cout << a << endl;
}

When I try to do something like

one->pointer = new double(5);

then I get a compiler error saying "query for the" pointer "element in" * (& one) → counted_ptr :: operator-> with T = double ", which has a non-class type double".

I was thinking of creating a function for this, and although I could make a T array allocation function, I can't think of a way to do this to select real objects. Any help is appreciated, thanks.

+3
6

?

counted_ptr& counted_ptr::operator=(T* p)
{
    if (! --*count) { delete count; }
    pointer = p;
    count = new int(1);
    return *this;
}

...

one = new double(5);

, , , , , * . , - :

counted_ptr::~counted_ptr() { if (! --*count) { delete pointer; delete count; } }

counted_ptr (, one = new double(5)) counted_ptr s, , -, ( ). :

  • ( ) .
  • counted_ptr . counted_ptr , ; , release retain. Objective-C, ( ). counted_ptr , 0 ( Obj-C). counted_ptr . , counted_ptr.

    smart_ptr, counted_ptr, smart_ptr, . smart_ptr counted_ptr release .

    counted_ptr shared_ptr.

. , . , , , counted_ptr, counted_ptr::~counted_ptr counted_ptr::release ( smart_ptr::~smart_ptr ) counted_ptr::release counted_ptr::_pointer ( ).

// counted_ptr owns its pointer an will free it when appropriate.
template <typename T>
class counted_ptr {
private:
    T *_pointer;
    size_t _count;

    // Make copying illegal
    explicit counted_ptr(const counted_ptr&);
    counted_ptr& operator=(const counted_ptr<T>& p);

public:
    counted_ptr(T* p=0, size_t c=1);
    ~counted_ptr();

    void retain();        // increase reference count.
    bool release();       // decrease reference count. Return true iff count is 0
    void reassign(T *p);  // point to something else.
    size_t count() const;

    counted_ptr& operator=(T* p);

    T& operator*() const;
    T* operator->() const;
};

template <typename T>
class smart_ptr {
private:
    counted_ptr<T> *_shared;
    void release();  // release the shared pointer
    void retain();   // retain the shared pointer

public:
    smart_ptr(T* p=0, int c=1);   // make a smart_ptr that points to p
    explicit smart_ptr(counted_ptr<T>& p); // make a smart_ptr that shares p
    explicit smart_ptr(smart_ptr& p); // copy constructor
    ~smart_ptr();

    // note: a smart_ptr brethren are the smart_ptrs that share a counted_ptr.
    smart_ptr& operator=(smart_ptr& p); /* Join p brethren. Doesn't alter pre-call
        * brethren. p is non-const because this->_shared can't be const. */
    smart_ptr& operator=(counted_ptr<T>& p);  /* Share p. Doesn't alter brethren. 
        * p is non-const because *this isn't const. */
    smart_ptr& operator=(T* p); // repoint this pointer. Alters brethren

    size_t count() const; // reference count

    T& operator*() const;  // delegate these to _shared
    T* operator->() const;

};

, , , .

+5

(, , ). Adatapost, "one=new double(5);" . : .

...
~counted_ptr() {
    --*count; 
    // deallocate objects whose last reference is gone.
    if (!*count) 
    {   
        delete pointer;
        delete count;
    }
}

counted_ptr& operator=(const counted_ptr& p)
{
    // be careful to accommodate self assignment
    ++*p.count;

    // may lose a reference here
    --*count;
    if (!*count)
    {
        delete pointer;
        delete count;
    }

    count=p.count;
    pointer=p.pointer;
    return *this;
}

, . , , .

private:
    /** remove our reference */
    void release()
    {
        --*count;
        if (!*count)
        {
            delete pointer;
            delete count;
        }
    }
+2

, "one.pointer=new double(5);"? "one->pointer=new double(5);" counted_ptr<double>::operator->. , :

double *tmp = one.operator->(); // returns one.pointer
tmp->pointer = new double(5);

, pointer.

+1

, - :

, , , - . , , outis . , , , , . , . , , -, , , .

, . , , .

+1

, use_count() boost::shared_ptr. , , - , . , ++.

0

, , operator = . " " , " ",

0

Source: https://habr.com/ru/post/1715751/


All Articles