下面是一个使用普通指针的简单例子:
MyClass *ptr = new MyClass();
ptr->doSomething(); //必须手动释放ptr,避免内存泄漏
使用智能指针,则不需要显式地调用delete去释放。智能指针是一个基于指针的类,重载了操作符*和->。智能指针的对象看起来像指针,但是可以做很多普通指针所不能的事情,例如自动析构(不需要显式使用delete),引用计数等。
总的方法是实现一个类,包含成员指针,析构函数以及重载操作符*和->。因为析构函数会在对象结束时自动调用,所以动态分配的资源可以被自动的delete(或者是引用计数自减)。
参考下面的例子:
#include<iostream>
using namespace std;
class SmartPtr {
int* ptr; // 实际的指针
public:
// 使用了explicit关键字的构造函数
explicit SmartPtr(int* p = nullptr) { ptr = p; }
// 析构函数
~SmartPtr() { if(ptr!=nullptr) delete(ptr); }
// 重载解引用操作符
int& operator *() { return *ptr; }
};
int main() {
SmartPtr ptr(new int());
*ptr = 20;
cout << "value is:" << *ptr << endl;
// 这里无需调用delete ptr。
// 当对象ptr的生命周期结束时,会自动调用析构函数来delete ptr。
return 0;
}
运行结果:
value is:20
对所有类型都通用的智能指针。
可以使用模板来实现一个通用的智能指针。如下面例子所示。
#include<iostream>
using namespace std;
// 一个通用的智能指针类
template <class T>
class SmartPtr {
T* ptr; // 实际的指针
public:
// 构造函数
explicit SmartPtr(T* p = nullptr) { ptr = p; }
// 析构函数
~SmartPtr() { if((ptr)!=nullptr) delete(ptr); }
// 重载解引用运算符
T& operator * () { return *ptr; }
// 重载箭头操作符,这样所有的T成员都能像指针一样访问。
// (当T是一个类或结构体或union时很有用)
T* operator -> () { return ptr; }
};
int main() {
SmartPtr<int> ptr(new int());
*ptr = 20;
cout << "value is:" << *ptr << endl;
return 0;
}
运行结果:
value is:20
智能指针可以很方便的用于资源管理,例如文件句柄,或网络sockets。
C++库中提供了这些智能指针auto_ptr, unique_ptr, shared_ptr and weak_ptr。