16.6效率與靈活性
這篇文章中c++ primer 用兩種智能指針舉例子
shared_ptr和unique_ptr如何指定刪除器的差異實際上就是這兩個類功能的差異。
我們先看一下如何定義shared_ptr的刪除器
學習自csdn的網址
https://blog.csdn.net/hp_cpp/article/details/103452196
在構造函數的時候傳入函數的指針:
#include <iostream>
#include <zconf.h>
#include "template.h"
using namespace std;
class Simple{
};
void deleter(Simple *)
{
cout<<"Deleter function called"<<endl;
}
// 構造函數傳遞自定義刪除器指針
int main() {
std::shared_ptr<Simple> p1(new Simple[5],deleter);
return 0;
}
在構造函數的時候使用仿函數
我們可以這樣看一個例子
class Deleter
{
public:
void operator() (Simple *x) {
std::cout << "Deleter function called" << std::endl;
delete[] x;
}
};
// 構造函數傳遞自定義刪除器指針
int main() {
Deleter del;
std::shared_ptr<Simple> p1(new Simple[5],del);
return 0;
}
我們通過運算符重載,可以將類重載成一個類似與函數的調用方式
Deleter del;
Simple* data = new Simple();
del(data);
這樣也會觸發Deleter function called
lambda表達式?
這個內容真的不是很懂,不知道什麼是lambda
std::shared_ptr<Sample> p3(new Sample[5], [](Sample *x) {
std::cout << "Deleter function called" << std::endl;
delete[] x;
});
第一次聽說c++ 的這個東西
下面我們看一下這個lambda表達式:
原來lambda表達式就是一個閉包,也就是我們俗話說的php中的匿名函數,基本是隻用一次所以也不需要函數名字,js中也有閉包
一個最簡單的lambda表達式
[] {} ();
void f()
{
}
int main()
{
f();
}
如果說這個瞭解了那上面的函數非常容易看懂了
#include <memory>
#include <cstring>
#include <vector>
#include <stdio.h>
#include <iostream>
#include <zconf.h>
#include "template.h"
using namespace std;
class Simple{
};
// 構造函數傳遞自定義刪除器指針
int main() {
std::shared_ptr<Simple> p1(new Simple[5],[](Simple* x){
std::cout << "Deleter function called" << std::endl;
delete[] x;
});
return 0;
}
第四種方式是使用default_delete
std::shared_ptr<Simple> p (new Simple[5],std::default_delete<Simple[]>());
我們再來看一下unique_ptr是如何指定刪除器的
unique_ptr 這種就不再贅述了,只是在模板中定義出函數,然後在傳入參數的時候做出實現就可以了
詳細的可以參考csdn
https://blog.csdn.net/hp_cpp/article/details/103210135
總結
最後我們可以看出shared_ptr並不是直接將刪除器保存爲一個成員,因爲刪除器的類型直到運行的時候纔會直到,實際上刪除器的類型我們可以隨時改變,unique_ptr的刪除器類型在編譯的時候就是知道的,unique_ptr避免了間接調用刪除器的開銷。通過運行時候綁定刪除器,shared_ptr使用戶重載刪除器更加方便。