C++ 智能指针

C++ 智能指针

指针用于存储另一个变量的地址。换句话说,指针提取了程序外部(堆内存)资源的信息。

我们使用资源的副本,并且要进行更改,是在副本上进行的。为了更改原始资源的内容,使用智能指针。

正常指针面临的问题

下面是一个描述正常指针问题的示例。

创建了一个名为 Rectangle 的类,具有两个数据成员(长度和宽度)。一个名为 fun() 的函数动态创建一个Rectangle对象。

当函数fun()结束时,对象p被销毁。由于我们没有删除p,内存仍然被分配,这个分配的资源将不可用于其他变量。

main() 函数中,我们执行一个无限循环,不断创建p对象并分配资源。这个问题最终导致 内存泄漏 ,而智能指针则是解决方案。

代码

#include 
using namespace std;

class Rectangle { // created a class Rectangle
private:
    int length; // data member as length of rectangle
    int breadth; // data member as breadth of rectangle

};

void fun() // the function to indicate the problem with normal pointer 
{

    Rectangle* p = new Rectangle(); // Create a dynamic object p 
}

int main()
{
    // Infinite Loop
    while (1) { // Run an infinite loop that will allocate p 
        fun();
    }
}

注意 – 诸如JAVAC#之类的语言具有智能地释放未使用的内存资源的垃圾回收器。

智能指针

我们将实现智能指针,以便它们可以释放未使用资源的内存。

创建一个带有指针、重载操作符 (->, *) 和析构函数的类。

当对象超出范围时,析构函数将自动调用,并自动删除动态分配的内存。

示例

#include 
using namespace std;

class SmartPtr { // Create the class to implement smart Pointer
    int* ptr; // Actual pointer
public:
// Create an explicit constructor 
    explicit SmartPtr(int* p = NULL) { ptr = p; }

    // Destructor to deallocate the resource used 
    ~SmartPtr() { delete (ptr); }

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

int main()
{
    SmartPtr ptr(new int());
    *ptr = 100;
    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;
}

输出

100

上述示例只适用于int类型。 我们将创建一个适用于每种数据类型的模板。

代码

#include 
using namespace std;

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

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

    // Overloading dereferncing 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 = 100;
    cout << *ptr;
    return 0;
}

输出

100

智能指针的类型

  • Unique_ptr

这种类型的对象仅存储一个对象。将另一个对象赋值给它时,当前对象将被解除分配。

代码:

#include 
#include 
using namespace std;


class Rectangle { // Create the class
    // Data members
    int length; // length of rectangle 
    int breadth; // breadth of rectangle 

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

    int area()
    { // calculate area
        return length * breadth; // return the area 
    }
};

int main()
{

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

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

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

    return 0;
}

输出

100
100 
  • Shared_ptr

在shared_ptr中,多个对象可以同时指向单个指针的同一个实例。使用use_count()方法来维护一个引用计数器,以便标记正在使用该对象的对象数量。

代码

#include 
#include 
using namespace std;

class Rectangle { // Create the class
    // Data members
    int length; // length of rectangle 
    int breadth; // breadth of rectangle 

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

    int area()
    { // calculate area of rectangle 
        return length * breadth; // return area 
    }
};

int main()
{

    shared_ptr P1(new Rectangle(20, 5)); // create shared //ptr P1
    // This'll print 100
    cout << P1->area() << endl;
    // Create shared ptr P2
    shared_ptr P2;
    P2 = P1;

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

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

// reference counter of P2 is 2   
    cout << P1.use_count() << endl; // prints 2 
    return 0;
}

输出

100
100
100
2
  • Weak_ptr

Weak_ptr与shared pointer相似。区别在于它不维护一个引用计数器,并且指针上没有对象的强引用。这个特性可能会导致死锁,因为不同的对象将会尝试持有这个指针。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程