Member 13277493 Ответов: 2

Об умных указателях


Мой вопрос касается конструктора копирования и оператора = overload в этом коде. Я понимаю это, но не совсем. Может кто-нибудь объяснить мне эти два выражения? Заранее спасибо!!!
#include <iostream>
using namespace std;

template <class T>

class Auto_ptr2{
private:
    T *m_ptr;
public:
    Auto_ptr2(T *ptr=nullptr)
    {


    }
    ~Auto_ptr2(){
    delete m_ptr;
    }
    Auto_ptr2(Auto_ptr2 &p)
    {
        m_ptr=p.m_ptr;
        p.m_ptr=nullptr;


    }
    Auto_ptr2 operator=(Auto_ptr2 &p)
    {
        if(&p==this){return *this;}
        else{
            delete m_ptr;
            m_ptr=p.m_ptr;
            return *this;

        }

    }
    T &operator*(){return *m_ptr;}
    T *operator->(){return m_ptr;}
bool isNull()const{return m_ptr==nullptr;}
};

class Resource{
public:
    Resource(){cout<<"Resource is acquired"<<endl;}
    ~Resource(){cout<<"Resource is destroyed"<<endl;}


};


int main()
{
    Auto_ptr2<Resource> res1(new Resource);
    Auto_ptr2<Resource> res2;
    cout<<"res1 is: "<<(res1.isNull()?"null":"not null")<<endl;
    cout<<"res2 is: "<<(res2.isNull()?"null": "not null")<<endl;
    res2=res1;
    cout<<"res1 is: "<<(res1.isNull()?"null":"not null")<<endl;
    cout<<"res2 is: "<<(res2.isNull()?"null": "not null")<<endl;


}


Что я уже пробовал:

Я пытался понять это, я понимаю это сейчас, но не совсем :)

Philippe Mori

Стандартный класс auto_ptr имеет известные проблемы... Итак, ваш код основан на его реализации. Если у вас есть современный компилятор C++, лучше использовать вместо него unique_ptr или shared_ptr.

2 Ответов

Рейтинг:
2

Philippe Mori

По сути, auto_ptr был попыткой перенести владение до C++ 11. Однако эта реализация имеет известные проблемы, поскольку язык в то время еще не имел ссылки rvalue и семантики перемещения...

По возможности используйте std::unique_ptr или std::shared_ptr.


Рейтинг:
1

KarstenK

В копии и конструкторе находятся назначения указателя элемента, который содержит необработанный указатель. Но это не только указатели, но и выделенная память, которая должен разбирайтесь отдельно.

Я бы осудил их а неправильный, не делая глубокой копии но удаление правой стороны.

Моя реализация

Auto_ptr2(const Auto_ptr2 &p)
{
    m_ptr= MakeCopy( p.m_ptr );//make a full copy of object
    //p.m_ptr=nullptr;
}
Auto_ptr2 operator=(const Auto_ptr2 &p)
{
    if(&p==this){return *this;}
    else{
        delete m_ptr;//correct deleting the old raw copy
        m_ptr=MakeCopy( p.m_ptr );
        return *this;
    }
}

Другим решением может быть так называемое архитектура подсчета ссылок, когда счетчик используется для управления жизненным циклом необработанных данных указателя.