智能指针与文件流
智能指针
C++文件流操作API
本章讲授的主要内容是智能指针的应用以及C++接口的文件操作。
因为C++文件操作相关API难用,相交C接口以及windows本地平台接口并没有带来相对的优势,因此本笔记不会记录C++文件操作的相关API
而C++中基本要杜绝『裸指针』的使用,推荐使用『智能指针』。
所谓智能指针,本质是通过添加一层包裹类,将这个类当做局部变量使用。局部变量超出作用域时编译器会调用其析构函数,因此在析构函数中配合『引用计数』来释放被包裹的类。
之所以要设计智能指针这样的类,本质的目的还是在于科学有效的管理堆内存。
被分配在堆中的内存何时被释放,是所有面向对象编程中(或者支持在堆中分配内存的语言中)必须要解决的问题。有的语言提供编译期的引用计数,有的是通过虚拟机的垃圾回收等机制。而C++并没有提供编译期的引用计数代码生成方案(如Objective-C),也没有提供垃圾回收机制,只提供用户态基于库函数的『智能指针』,理论上,用户自己也能实现属于自己的智能指针类,但是存在诸多繁复细节要考虑(如需要准确识别包裹的是对象还是对象数组等),因此并不推荐用户自行使用自定义的智能指针包裹类。直接使用语言库提供的指针智能类。
智能指针之share_ptr
被定义在堆上的对象,既可能被A指针引用,又可能被B指针引用,能够在各种函数调用中被传递,因此,当我们定义的对象符合可能被多个指针引用(持有)时,则需要使用share_ptr类
#include <iostream>
using namespace std;
class Node{
public:
Node(){}
};
void handleNode(shared_ptr<Node> node){
//do something...
}
int main(){
//通过shared_ptr类包裹住分配在堆内存中的Node对象,shared_ptr是一个模板类,又被称为智能指针
shared_ptr<Node> node(new Node);
//之所以叫shared_ptr是因为这个类包裹的堆对象允许被多个对象引用持有,反言之,当我们定义的堆对象允许被多重持有时,则需要使用shared_ptr进行包裹
shared_ptr<Node> node2 = node;
handleNode(node2);
//智能指针支持创建对象数组
shatrd_ptr<Node[]> nodes(new Node[3]);
return 0;
}
被智能指针包裹后的堆裸指针不再需要手动进行delete释放对象,自动被shared_ptr管理了
除此外,当我们定义的堆对象不允许或者说只能被单个对象持有时,则需要使用unique_ptr
#include <iostream>
using namespace std;
class Node{
public:
Node(){}
};
int main(){
unique_ptr<Node> node(new Node);
//当另一个对象需要持有堆对象node时,需要使用的语义是『转移』,也就是说堆对象始终只会被一个对象(指针)持有
unique_ptr<Node> node2 = move(node);
return 0;
}
智能指针内部也是基于『引用计数』原理对堆内存进行管理的。
但凡有引用计数的地方就有循环引用,循环引用产生的原因在于引用计数的无区别增加。因此需要能够控制引用计数是否增加,这时C++提供了另一个类weak_ptr,被weak_ptr包裹的堆对象引用计数并不会增加。通常,在处理循环引用时需要用到weak_ptr。
#include <iostream>
using namespace std;
class Node{
public:
Node(){}
};
int main(){
shared_ptr<Node> node(new Node);//此时node引用计数为1
shared_ptr<Node> node2 = node;//此时node引用计数为2
//weak_ptr并不会使得对象引用计数增加
weak_ptr<Node> node3 = node2;////此时node引用计数依旧2
return 0;
}
posted on 2021-12-28 00:17 shadow_fan 阅读(125) 评论(0) 编辑 收藏 举报