c++ - 当内存被其他对象使用时不要删除ptr

标签 c++ pointers

我创建了 ABC 类,并通过普通、分配和复制构造函数创建了它的三个对象。现在它们为 ptr 使用相同的内存地址。

当这些对象被删除时意味着超出范围,然后第一个对象被删除,但是第二个是内存已经被删除的错误。 这可以。我明白了。

#include<iostream>
using namespace std;

class ABC
{
    private:
        int a;
        int *ptr;

    public:
        ABC();                      // Simple constructor.
        ABC(int a, int b);          // Parameterized constructor.
        ABC(const ABC &obj);        // Copy constructor.
        ~ABC();                     // Destructor.
        void display();             // Display.
        ABC& operator=(const ABC &obj); // Operator Overload.
};


ABC::ABC() 
{

}


ABC::ABC(int a, int b) 
{
    cout << "Parameterized constructor" << endl;
    // allocate memory for the pointer;
    this->a = a;   
    ptr = new int;
    ptr = &b;
}


ABC::ABC(const ABC &obj) 
{
    cout << "Copy constructor" << endl;
    a = obj.a;
    //ptr = new int;
    //*ptr = *obj.ptr; // copy the value
    ptr = obj.ptr; 
}


ABC& ABC :: operator=(const ABC &obj) 
{
    cout <<"Assignemnt operator overload"<<endl;
    this->a = obj.a;
    this->ptr = obj.ptr;
    return *this;
}


ABC::~ABC(void) 
{
   cout << "Freeing memory!" << endl;
   delete ptr;
}


void ABC::display() {
    cout << "a value = : " << a <<endl;
    cout << "ptr value = : " << ptr <<endl;
    cout << "*ptr value = : " << *ptr <<endl;
}


int main()
{
    // Normal.
    ABC obj1(1, 2);
    cout << "Point Obj1 value = : "<<endl;
    obj1.display();

    cout<<"\n\n";
    // Assignment.
    ABC obj2;
    obj2 = obj1;
    cout << "Point Obj2 value = : "<<endl;
    obj2.display();

    cout<<"\n\n";
    // Copy constructor.
    ABC obj3(obj1);
    cout << "Point Obj3 value = : "<<endl;
    obj3.display();

    return 0;
}

我想做的是,我不想在其他对象正在使用时删除内存。如何通过智能指针处理这个问题,我不想通过内置剪切指针来处理。我想编写智能指针类并在其他对象使用相同内存时增加 ptr 引用计数。但是不知道怎么办。

class SmartPointer
{

    public:
        int *ptr;
        int ref;
        SmartPointer();
        SmartPointer(int *p);
        int& operator *();
        ~SmartPointer();
};

SmartPointer::SmartPointer()
{
    cout<<"SmartPointerInitilaize default"<<endl;
    ref = 1;
}


SmartPointer::SmartPointer(int *p)
{
    cout<<"SmartPointerInitilaize para"<<endl;
    ptr = p;
    ref = 1;
}

int& SmartPointer:: operator *()
{  
    return *ptr; 
}

SmartPointer::~SmartPointer()
{

    cout<<"SmartPointer De-Initilaize"<<endl;
    //delete ptr;
}

最佳答案

您基本上想要做的是实现一个std::shared_ptr。您通常不应该这样做,因为它非常棘手,但是出于教育目的并了解其工作原理:

1) 引用计数需要是传递的指针数据的一部分(如果不是静态的),由所有“链接的”SmartPointer 实例共享。

2) 您仍然需要定义复制构造函数/赋值运算符来增加引用计数。在析构函数中减少引用计数,如果为零,则删除指针(和额外数据)。

一个例子:

class SmartPointer
{

   struct Data {
        Data(int *p)
            : ptr(p)
            , ref(1)
        {}
        ~Data() {Release();}
        void Acquire() {
            ++ref;
        }
        void Release() {
            if (!--ref) { delete ptr; delete this; }
        }
        int *ptr;
        int ref;
   };

        Data *data;
    public:
        SmartPointer()
            : data(new Data(NULL))
        {}
        SmartPointer(int *p)
            : data(new Data(p))
        {}
        SmartPointer(const SmartPointer& x)
            : data(x.data)
        { data->Acquire(); }
        SmartPointer& operator =(const SmartPointer& x)
        {
            if (this != &x) {
                data->Release();
                data = x.data;
                data->Acquire();
            }
        }
        int& operator *() { return *data->ptr; }
        ~SmartPointer() { data->Release(); }
};

请注意,这是非常简化的(例如,不是线程安全的),只是基本思想。

实际的 std 或 boost shared_ptr 要复杂得多(模板化,支持涉及类型删除等的自定义删除器)。

关于c++ - 当内存被其他对象使用时不要删除ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41462702/

相关文章:

c++ - 删除指针和将其设置为 nullptr 之间有什么区别?

python - 如何使用 python 将指针输入发送到 C++ 程序?

c++ - 奇怪的重复模板模式 : double inheritance

c++ - 为什么我不能对控制流图 (CFG) 进行拓扑排序?

pointers - 在 Go 中传递任意 slice

c - 为什么程序不断打印垃圾值?

c++ - 为二维char数组分配内存,错误: invalid conversion from ‘void*’ to ‘char**’

c++ - 如何在 qgraphicsview 中进行非平滑/逐步滚动

c++ - 'using' 和 'using namespace' 之间的区别

c++ - 是否有可能在没有得到 "new"ed 的结构中有一个 boost::variant?