传统指针
#include <iostream>
#include <memory>
#include <stdio.h>
using namespace std;
// 传统指针
void defaultAlloc(){
int amtToStore;
cout <<"How many numbers do you want to store : ";
cin >>amtToStore;
int* pNums;
pNums = new int[amtToStore];
if(pNums !=NULL){
int i =0;
while(i<amtToStore){
cout <<"Enter a Number : ";
cin >> pNums[i];
i++;
}
}
cout <<"You entered these numbers"<<endl;
for(int i=0;i<amtToStore;i++){
cout <<pNums[i]<<endl;
}
delete pNums;
}
int main(){
defaultAlloc();
return 0;
}
通常情况下我们使用上面的方式来分配空间.通过前面
内存四区
模型 我们知道 我们这里实在堆上面分配内存的,也就意味着需要我们手动去释放。当工程量大了之后我们很容易疏忽,忘记去释放内存,这时就会发生内存泄露问题,或者释放了一个正在使用的指针,从而造成非法内存,这些问题都是非常致命
的,为了改善这一现状C++11
中引入了智能指针。
编译参数
g++ ..... -std=c++11
因为 智能指针是C++11引入的,所以我们在编译时,需要指定为 c++11
智能指针
在使用智能指针前,我们还需要引入一个头文件
#include<memory>
- shared_ptr
- unique_ptr
- weak_ptr
shared_ptr
多个 shared_ptr 对象可以共同托管一个指针 p,当所有曾经托管 p 的 shared_ptr 对象都解除了对其的托管时,就会执行delete
- get 获取当前托管的指针
- reset 托管新的指针
#include <iostream>
#include <memory>
/*
* @author luzhenfang
* @date 2020 10 18
* @desc modern cpp smartPointer
*/
class Elem {
protected:
int mIndex;
public:
Elem(int i) : mIndex(i) { std::cout << "Constructor : " << mIndex << std::endl; };
virtual ~Elem() { std::cout << "Destructor : " << mIndex << std::endl; };
int getElem() const { return mIndex; }
};
int main() {
// shared_ptr
// 一个指针 多个托管对象
std::shared_ptr<Elem> sp1(new Elem(1));
std::shared_ptr<Elem> sp2(sp1);
std::shared_ptr<Elem> sp3;
sp3 = sp2;
std::cout << sp1->getElem() << std::endl;
// 拿到托管指针
auto p = sp2.get();
std::cout << "p : " << p->getElem() << std::endl;
// sp1 重新托管 E2
sp1.reset(new Elem(2));
// sp2 重新托管 E3
sp2.reset(new Elem(3));
// sp3 重新托管 E4 此时 E1 没人托管 被 delete
std::cout <<"------"<<std::endl;
sp3.reset(new Elem(4));
// sp1 重新托管E5 导致 E2 没人托管 delete
sp1.reset(new Elem(5));
return 0;
}
unique_ptr
与 shared_ptr 不同,只能用 new 分配内存,独占不可共享
- 不允许拷贝和赋值
#include <iostream>
#include <memory>
using namespace std;
int main(){
// 智能指针
int amtToStore;
cout <<"How many numbers do you want to store : ";
cin >>amtToStore;
unique_ptr<int[]>pNums(new int[amtToStore]);
if(pNums!=NULL){
int i=0;
while(i<amtToStore){
cout <<"Enter a number : ";
cin >>pNums[i];
i++;
}
}
cout <<"Your entered these numbers "<<endl;
for(int i=0;i<amtToStore;i++){
cout <<pNums[i]<<endl;
}
return 0;
}
weak_ptr
主要用来解决循环引用问题
- 弱引用 不会对计数叠加
- 只能从 shared_ptr 或者 weak_ptr 构造而来
#include <iostream>
#include <memory>
/*
* @author luzhenfang
* @date 2020 10 18
* @desc modern cpp smartPointer
*/
int main() {
std::shared_ptr<std::string> sp1(new std::string("Hello CPP"));
std::cout <<"sp1 use_count "<<sp1.use_count()<<std::endl;
std::weak_ptr<std::string>wp1(sp1);
std::cout <<"wp1 use_count "<<wp1.use_count()<<std::endl;
std::weak_ptr<std::string>wp2(wp1);
std::cout <<"wp2 use_count "<<wp1.use_count()<<std::endl;
// 没过期
if (!wp2.expired()){
auto sp2 = wp2.lock();
std::cout <<"sp2 " <<*sp2<<std::endl;
}
// 置空
wp2.reset();
// 过期了
if (wp2.expired()){
std::cout <<"wp2 expired"<< std::endl;
}
return 0;
}