C++11(RAll智能指针)
更多教程笔记请查看我的上一篇文章:点击跳转
C++11(RAll智能指针)自学之旅开始!
本次将介绍C++11最有用的更新:智能指针
长久以来C++的内存管理机制就一直被人诟病,没有GC回收,需要手动释放分配的内存,很容易被忘记释放内存的程序员造成内存泄漏,甚至被linux之父Linus炮轰C++是一门很烂的语言
详情请点击这里
但是C++也在不断的改进自身,不断的吸取教训,我相信C++未来会越来越好!
说回话题本身,智能指针是一个可以帮助C++程序员自动释放所分配内存的强大利器,不过用得好和用不好是两回事,下面我们来看一下智能指针的诞生原因:
概念代码:
//智能指针
#include <iostream>
#include "stdfix.h"
using namespace std;
// c语言当中对文件的操作
FILE *open_file(char *name)
{
FILE *fp = NULL;
fp = fopen(name, "rb++");
return fp;
}
class CTest
{
public:
CTest()
{
cout << "构造函数" << endl;
//申请堆区资源
m_pInt = new int;
}
~CTest()
{
cout << "析构函数" << endl;
if (m_pInt != nullptr)
{
//释放资源
delete m_pInt;
m_pInt = nullptr;
}
}
private:
int *m_pInt;
};
//创建一个全局对象,全局对象有构造有析构,在对象创建和销毁前编译器都会主动调用构造和析构函数
//利用这个机制即可解决手动释放资源所带来的问题
CTest test;
int main()
{
// c++需要自己管理堆内存的申请和释放
int *p = new int;
delete p;
//有的时候会忘记资源的释放导致资源泄漏
return 0;
}
看明白了吧,在对象创建和销毁前编译器都会主动调用构造和析构函数,这便是智能指针诞生的原因
智能指针便是简化了上述操作,在对象创建后由智能指针来接管,就算不手动释放内存,智能指针也会自动调用析构帮你释放,不得不说C++真是太强大了!
话不多说,我们一起来看看智能指针的实际操作:
实战代码:
//智能指针-unique_ptr独占指针
#include <iostream>
#include <string>
//想用智能指针必须包含这个头文件
#include <memory>
using namespace std;
class Cat
{
public:
//默认构造
Cat() = default;
//有参构造函数
Cat(string name)
{
this->m_Name = name;
}
//析构函数
~Cat()
{
cout << "Destructor of Cat: " << m_Name << endl;
}
//成员函数 默认不可修改
void cat_info() const
{
cout << "cat info name: " << m_Name << endl;
}
string get_name() const
{
return m_Name;
}
//将内部的m_Name修改
void set_cat_name(const string &name)
{
this->m_Name = name;
}
private:
//创建一个变量给予默认值
string m_Name{"Mimi"};
};
int main()
{
//调用有参构造和成员函数
Cat c1("ok");
c1.cat_info();
//下面是局部作用域,在结束前会自动调用析构
{
Cat c1("ok");
c1.cat_info();
}
//在堆区开辟内存并调用有参构造
Cat *c_p1 = new Cat("yy");
c_p1->cat_info();
{
Cat *c_p1 = new Cat("yy_scope");
c_p1->cat_info();
//手动释放
delete c_p1;
}
//手动释放
delete c_p1;
//手动释放非常的不安全,所以需要智能指针
//智能指针会自动的释放内存,不需要手动释放
// unique_ptr的第一种用法:
//向堆区申请内存
Cat *c_p2 = new Cat("yz");
//创建一个智能指针指向那个指向堆区内存的指针
unique_ptr<Cat> u_c_p2{c_p2};
c_p2->cat_info();
u_c_p2->cat_info();
//当指针内部的变量修改后
c_p2->set_cat_name("ok");
//智能指针也会修改
u_c_p2->cat_info();
delete c_p2;
c_p2 = nullptr;
//当堆区的内存释放后就无法再通过智能指针调用了
// u_c_p2->cat_info();
//第二种用法:
//在堆区创建时就用智能指针指向那个指向堆区内存的指针
unique_ptr<Cat> u_c_p3{new Cat("dd")};
u_c_p3->cat_info();
u_c_p3->set_cat_name("oo");
u_c_p3->cat_info();
//第三种用法 利用make_unique默认创建,调用默认构造函数
unique_ptr<Cat> u_c_p4 = make_unique<Cat>();
u_c_p4->cat_info();
u_c_p4->set_cat_name("oo");
u_c_p4->cat_info();
// get和常量类型
unique_ptr<int> u_i_1{new int(100)};
//通过get就可以打印int的地址
cout << "int address: " << u_i_1.get() << endl;
cout << "cat address: " << u_c_p3.get() << endl;
//解引用
cout << *u_i_1 << endl;
unique_ptr<int> u_i_p2 = make_unique<int>(200);
cout << *u_i_p2 << endl;
cout << u_i_p2.get() << endl;
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 一生雾梦!
评论
ValineDisqus