openfoam 智能指针探索
前言
今天看到一个程序,用到了智能指针,
virtual tmp<volScalarField> rho() const;
借此机会把有关智能指针的知识体系重新梳理一遍
智能指针autoPtr的由来:
首先要说明智能指针本质上是模板类,是对原有指针的改进,相比更安全,
of中的智能指针autoPtr很像原有的auto_ptr,但不是对原有的封装,而是重新写了一遍
of对autoPtr的描述如下:
An auto-pointer similar to the STL auto_ptr but with automatic casting
to a reference to the type and with pointer allocation checking on access.
std::auto_ptr的定义大致如下:
template <typename _Tp>
class auto_ptr
{
private:
_Tp *_M_ptr;
public:
explicit auto_ptr(_Tp *__p = 0) throw();
auto_ptr(auto_ptr &__a) throw();
auto_ptr &operator=(auto_ptr &__a) throw();
~auto_ptr();
_Tp &operator*() const throw();
_Tp *operator->() const throw();
_Tp *get() const throw();
_Tp *release() throw();
void reset(_Tp *__p = 0) throw();
};
再看咱of中的autoPtr是何其相似,但实现方法肯定各有千秋
template<class T>
class autoPtr
{
mutable T* ptr_;
public:
typedef T Type;
inline explicit autoPtr(T* = nullptr);
inline autoPtr(const autoPtr<T>&);
inline autoPtr(const autoPtr<T>&, const bool reuse);
inline ~autoPtr();
inline bool empty() const;
inline bool valid() const;
inline T* ptr();
inline void set(T*);
inline void reset(T* = nullptr);
inline void clear();
inline T& operator()();
inline const T& operator()() const;
inline T& operator*();
inline const T& operator*() const;
inline operator const T&() const;
inline T* operator->();
inline const T* operator->() const;
inline void operator=(T*);
inline void operator=(const autoPtr<T>&);
};
在autoPtr中,我们也能看到在autoPtr中加了很多unique_ptr的元素,比如说reset(),
了解of中的智能指针的来源,那么为什么要用智能指针呢,他的应用场景是哪些,下次我们自己写的时候要什么时候用
为什么要用智能指针:
举个例子,比如说我们要实现插值算法,用matlab写,这很简单
result = function(input)
现在我们学习C++了,知道了可以传指针或引用,可以这样写
function(&result, input);
相比之下of更倾向于使用matlab的书写方式
因为简单
不仅是看起来简单,写起来也简单,可以更直观的表达想法
对于没接触过C或C++的人来说,不必了解引用左值右值等一系列知识
在of中写动量方程,
fvVectorMatrix UEqn
(
fvm::ddt(rho, U)
+ fvm::div(rhoPhi, U)
+ turbulence->divDevRhoReff(rho, U)
);
首先这是个类fvVectorMatrix的构造函数,还是个拷贝构造
那这就需要类内部的重载以及函数返回类型都是fvVectorMatrix类
对于需要引入方程的人来说这样写很明显更直观更简单
但是C++作为效率最高的语言,引用这个概念的提出肯定有他的道理
我们一般说引用是什么,很多说是别名,实际上没有说到本质
引用的本质是指针常量,如果换C语言的写法是这样的
int* const rb = &a;
matlab以简单易用著称,但用过matlab的人都知道matlab的效率极低,
本科时候当时不会向量化编程,参加数学建模比赛跑一个循环,跑了整整24小时,笔记本散热也不大行,后来送修主板了
为什么matlab效率低,很关键的一点是matlab一直都是复制拷贝
C/C++指针传地址效率就高很多,况且C++引用的本质就是指针
在简单易用和效率之间,matlab选择了前者,C++选择了后者
openfoam是一个非常强大的张量计算程序,既不能舍弃易用性抬高门槛,又不能反复使用复制拷贝降低效率,稀疏矩阵那么大拷贝来拷贝去算一个程序跑好几年成本太高
openfoam使用智能指针解决了这个问题,看起来不难读懂又能保证效率,这也就回答了为什么要使用智能指针
再回到我们刚刚说的动量方程拷贝构造上,首先在书写方法上依旧是matlab的显式书写方法,但实际上是C++的隐式移动拷贝
可能现在依旧疑惑在哪里看到用指针了,可以打开fvm命名空间的内容
namespace fvm
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
tmp<fvMatrix<Type>>
d2dt2
(
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
return fv::d2dt2Scheme<Type>::New
(
vf.mesh(),
vf.mesh().d2dt2Scheme("d2dt2(" + vf.name() + ')')
).ref().fvmD2dt2(vf);//这里返回的可是fvMatrix<Type>类型指针
}
template<class Type>
tmp<fvMatrix<Type>>
d2dt2
(
const dimensionedScalar& rho,
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
return fv::d2dt2Scheme<Type>::New
(
vf.mesh(),
vf.mesh().d2dt2Scheme("d2dt2(" + rho.name() + ',' + vf.name() + ')')
).ref().fvmD2dt2(rho, vf);
}
template<class Type>
tmp<fvMatrix<Type>>
d2dt2
(
const volScalarField& rho,
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
return fv::d2dt2Scheme<Type>::New
(
vf.mesh(),
vf.mesh().d2dt2Scheme("d2dt2(" + rho.name() + ',' + vf.name() + ')')
).ref().fvmD2dt2(rho, vf);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fvm
看到了嘛,随便一个遍布tmp智能指针,在指针赋值时就已经完成了类的初始化
但又因为只是指针,可以用显式的方法去写,只要保证返回类型相同即可
fvm += fvc::surfaceIntegrate
(
faceFlux*tinterpScheme_().correction(vf)
);
表面上是大型矩阵相加减,实际上是智能指针这个地址在执行重载,极大的提升了效率
打个比方,这就像高启强要和赵立冬或孟德海商量一件事,赵这个级别的不方便出面,出面的都是龚开疆或王秘书这样的人,又能传达指示又不消耗大量资源,好处就是双方都留有余地
智能指针智能的点就在于不需要或者出问题的时候能自动销毁,打开相关析构函数
template<class T>
inline Foam::tmp<T>::~tmp()
{
clear();
}
template<class T>
inline void Foam::tmp<T>::clear() const
{
if (isTmp() && ptr_)
{
if (ptr_->unique())
{
delete ptr_;
ptr_ = 0;
}
else
{
ptr_->operator--();
ptr_ = 0;
}
}
}
tmp析构时对该智能指针进行了delete,
记得狂飙里调查组一来最先销毁的也是龚开疆这个智能指针,,,
这样openfoam无需g++ -o优化也能有很好的运行效率
autoPtr与tmp的使用场合与区别
在openfoam中,autoPtr是强引用类型智能指针,tmp是弱引用类型智能指针
那我们在什么时候使用autoPtr以及tmp呢
autoPtr多使用在transport models ,boundry conditions,discretization schemes,turbulenceModel,interpolation schemes,gradient schemes或fvOptions这种动态多态中,更适合析构频次高的地方,智能指针autoPtr能够自动析构,因而被广泛使用
autoPtr<incompressible::RASModel> turbulence
(
incompressible::RASModel::New(U, phi, laminarTransport)
);
autoPtr一旦有所指向只能移动,不能复制,同名同类型只能指向一个对象
再说tmp,之前有博客说tmp类似shared_ptr,实际上tmp的自我介绍中并没有像autoPtr一样提及相关类auto_ptr,和shared_ptr也不是继承关系,但实现功能很接近
A class for managing temporary objects.
tmp的自我介绍中说是管理临时变量的类,这个介绍更像是我们日常做的副本,就像我现在做的博客,害怕自己忘做份笔记,日后翻看,当然这个博客的建立首先是自己做好了理解,因而类似的,tmp的构造需要autoPtr在前面已经做好了指定,tmp配合进行副本引用
tmp的销毁和shared_ptr一致,具体可以见shared_ptr
一起探索openfoam也是相当有趣的一件事,非常欢迎私信讨论
指正的价值要比打赏更重要,下面是个人联系方式,希望能结交到志同道合的朋友
openfoam 智能指针探索的更多相关文章
- 基于C/S架构的3D对战网络游戏C++框架_05搭建系统开发环境与Boost智能指针、内存池初步了解
本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...
- 智能指针和异常、 weak_ptr、unique_ptr
12.1.4智能指针和异常 1.在块中创建的动态内存,如果是由内置指针来指向这块内存,那么若是在块结束时未delete这个指针,则该内存不会被释放,若在delete之前发生异常,由于还没执行delet ...
- C++ | 再探智能指针(shared_ptr 与 weak_ptr)
上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了.那么本章我们就来探索 boost库和C++11中的智能指针以 ...
- enote笔记法使用范例(2)——指针(1)智能指针
要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...
- C++11 shared_ptr 智能指针 的使用,避免内存泄露
多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...
- C++智能指针
引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...
- EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针
一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...
- 智能指针shared_ptr的用法
为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...
- 智能指针unique_ptr的用法
unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...
- C++ 引用计数技术及智能指针的简单实现
一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧).最近花了点时间认真看了智能指针,特地来写这篇文章. 1.智能指针是什么 简单来说,智能指针是一个类,它对普 ...
随机推荐
- python多进程程序打包成exe的问题
粘贴一下部分的多进程代码 if __name__ == '__main__': """"流程模拟""" multiprocessi ...
- 【转载】EXCEL VBA 通过VBA中的Union合并多个Range选择区域
在Excel中,Union的功能是合并两个或两个以上的选择区域,合并成为一个更大的区域. 所合并的多个选择区域,这些选择区域,可以是不连续的,也可以是连续的.一般情况下,要使用Union,可通过如下来 ...
- 【转载】SQL SERVER 表变量与临时表的优缺点
什么情况下使用表变量?什么情况下使用临时表? -- 表变量: DECLARE @tb table(id int identity(1,1), name varchar(100)) INSERT @tb ...
- 一、对称加密(DES加密)
一.DES简介DES是一种对称加密(Data Encryption Standard)算法.于1977年得到美国政府的正式许可,是一种用56位密钥来加密64位数据的方法.一般密码长度为8个字节,其中5 ...
- [LeetCode]二进制求和
题目 代码 class Solution { public: string addBinary(string a, string b) { int lenA = a.length(); int len ...
- SwiftUI(二)
也许很多人看完一会有一个疑问,为什么UIHostingController我这里报错呢 看到这里大家心中的疑问也就解开了 接下来给大家说下@State的作用 通过@State swiftUI实 ...
- Java集合 - ConcurrentHashMap
介绍 ConcurrentHashMap 技术是为了解决问题而生的,ConcurrentHashMap 解决了多个线程同时操作一个 HashMap 时,可能出现的内部问题.当多个线程同时操作一个 Ha ...
- [硬核] Bootstrap Blazor Table 综合演示例子
知识点: 1.导入导出 2.分页功能 3.增删改查 4.批量删除 5.批量编辑(审核) 6.列排序与列搜索 7.顶部搜索实现所有列搜索 8.高级搜索实现多条件搜索 9.顶部与刷新与视图列 10.实现文 ...
- Scrapy爬虫框架快速入门
安装scrapy pip install scrapy -i https://pypi.douban.com/simple/ 安装过程可能遇到的问题 版本问题导致一些辅助库没有安装好,需要手动下载并安 ...
- 如何进行动态ip的域名解析设置?
如何进行动态ip的域名解析设置?目前,有一部分域名客户出于节省成本.技术验证等因素,会把自己家里或是部门的电脑用来当做Web服务器.mail服务器或是ftp服务器.如果想提供给其他人长期浏览,一般都要 ...