C++ 智能指针

C++ 智能指针

指针用于访问程序之外的资源,如堆内存。因此,指针被用于访问堆内存(如果在堆内存中创建了任何东西)。在访问任何外部资源时,我们只需使用它的副本。如果要进行任何更改,只需在复制的版本中更改即可。但是,如果使用指向资源的指针,则可以更改原始资源。

普通指针的问题

查看下面的代码。

#include 
using namespace std;

class Rectangle {
private:
    int length;
    int breadth;
};

void fun()
{
    // By taking a pointer p and
    // dynamically creating object
    // of class rectangle
    Rectangle* p = new Rectangle();
}

int main()
{
    // Infinite Loop
    while (1) {
        fun();
    }
}

函数fun生成一个指向Rectangle对象的指针。矩形由两个整数组成:长和宽。因为p是一个局部变量,它将在函数结束时被销毁。但是,因为我们忘了使用delete p;在函数结束时,它所消耗的内存将不会被释放。这意味着内存将不能被其他资源使用。但是,我们不再需要变量,而是需要内存。

Fun在main函数的无限循环中被调用。这意味着它将继续生成p。它将分配更多的内存,但不会释放它,因为我们没有释放它。未使用的内存不能再次使用。这将导致内存泄漏。因此,整个堆内存可能变得无用。c++ 11的一个特性——智能指针(Smart Pointer)为这个问题提供了一个解决方案。

智能指针正在被引入

不知不觉中,不处理指针的定位会导致内存泄漏,从而可能导致程序崩溃。垃圾收集机制在Java和c#语言中被用于智能地释放未使用的内存,以便再次使用它。程序员不必担心内存泄漏。智能指针是c++ 11开发的一种机制。当对象被销毁时,内存也被释放。因此,我们不需要删除它,因为Smart Pointer会处理它。

Smart Pointer是一个指针包装类,重载了*和->等操作符。智能指针类的对象类似于普通指针。然而,与普通指针不同的是,它有释放和释放已销毁对象内存的能力。

接受一个具有指针、析构函数和重载操作符(如*和->)的类。因为析构函数是在对象退出作用域时自动调用的,动态分配的内存将被删除(或者引用计数可以减少)。考虑下面所示的SmartPtr类。

#include 
using namespace std;

class SmartPtr {
    int* ptr; // Actual pointer
public:
    // for use of explicit keyword
    explicit SmartPtr(int* p = NULL) { ptr = p; }

    // Destructor
    ~SmartPtr() { delete (ptr); }

    // Overloading dereferencing operator
    int& operator*() { return *ptr; }
};

int main()
{
    SmartPtr ptr(new int());
    *ptr = 20;
    cout << *ptr;

    // We don't need to call delete ptr: when the object
    // ptr goes out of scope, the destructor for it is automatically
    // called and destructor does delete ptr.

    return 0;
}

输出:

20

这只适用于int。所以我们需要为每个对象创建一个智能指针?不,模板,有办法。从下面的代码中可以看到,T可以是任何类型。

#include 
using namespace std;

// A generic smart pointer class
template 
class SmartPtr {
    T* ptr; // Actual pointer
public:
    // Constructor
    explicit SmartPtr(T* p = NULL) { ptr = p; }

    // Destructor
    ~SmartPtr() { delete (ptr); }

    // Overloading dereferencing operator
    T& operator*() { return *ptr; }

    // Overloading arrow operator so that
    // members of T can be accessed
    // like a pointer (useful if T represents
    // a class or struct or union type)
    T* operator->() { return ptr; }
};

int main()
{
    SmartPtr ptr(new int());
    *ptr = 20;
    cout << *ptr;
    return 0;
}

输出:

20

注意: 智能指针还可以用于管理资源,如文件句柄或网络套接字。

智能指针类型

1. unique ptr

只有一个指针存储在唯一的ptr中。通过从指针中移除当前对象,我们可以给一个不同的对象赋值。请注意下面的代码。首先,unique_pointer指向P1。但是,我们移除P1,用P2替换它,所以指针现在指向P2。

C++ 智能指针

#include 
using namespace std;
#include 

class Rectangle {
    int length;
    int breadth;

public:
    Rectangle(int l, int b){
        length = l;
        breadth = b;
    }

    int area(){
        return length * breadth;
    }
};

int main(){

    unique_ptr P1(new Rectangle(10, 5));
    cout << P1->area() << endl; // This'll print 50

    // unique_ptr P2(P1);
    unique_ptr P2;
    P2 = move(P1);

    // This'll print 50
    cout << P2->area() << endl;

    // cout<area()<

输出:

50
50

2. shared_ptr

使用共享ptr,多个指针可以同时指向同一个对象,它将使用use count()方法保持一个引用计数器。

C++ 智能指针

#include 
using namespace std;
#include 

class Rectangle {
    int length;
    int breadth;

public:
    Rectangle(int l, int b)
    {
        length = l;
        breadth = b;
    }

    int area()
    {
        return length * breadth;
    }
};

int main()
{

    shared_ptr P1(new Rectangle(10, 5));
    // This'll print 50
    cout << P1->area() << endl;

    shared_ptr P2;
    P2 = P1;

    // This'll print 50
    cout << P2->area() << endl;

    // This'll now not give an error,
    cout << P1->area() << endl;

    // This'll also print 50 now
    // This'll print 2 as Reference Counter is 2
    cout << P1.use_count() << endl;
    return 0;
}

输出:

50
50
50
2

3. weak_ptr

它非常类似于共享ptr,除了它不保留引用计数器。在这种情况下,指针不会在对象上有据点。这样做的原因是,如果指针在请求其他对象时持有该对象,它们可能会形成死锁。

C++ 智能指针

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程