su_junwei 发表于 2009-7-21 03:47:19

[转贴]OpenFOAM中的智能指针autoPtr

OpenFOAM中有两个常用但很难理解的模板类,智能化指针模板类autoPtr和瞬态对象操作模板类tmp。这两个类几乎无处不在,使用极易出错。OpenFOAM通过该自动指针来实现对象的多态创建。这使得你可以在不改变程序的情况下,完成多种不同实现。本文意在探讨,这autoPtr的使用过程中应当注意的问题及其他们与标准c++指针的差别。瞬态对象操作模板类tmp的使用,后续文章探讨。

C++语言中数据的传递方式有两种:(1)数值传递(2)地址传递。前者是在函数调用中将实参的值复制一份传给形参,形参的变化不会影响到实参。后者在函数调用中传递的实际参数的地址,在函数中,对形参的修改会影响到实参。这点可以参考谭老的c语言经典之作“c语言程序设计”,不再累叙。 就地址传递而言,C语言采用指针,而C++中可以采用引用。两者在参数传递的时候效果一样,C++引用相对来说比较简单,但是灵活性较指针差一些。 比如:如果想实现,父类声明对象,子类构造该对象,只能通过指针来完成,因为指针可以悬空,而引用则不行。两者的差别,可以参看相应C++书籍。 闲言少序。

1.autoPtr
使用:autoPtr<className> objectName;

特性1:指针自动释放
autoPtr可实现类className的指针操作,但此指针会自动释放,因此无需手动释放。这是和C++标准指针最大的差别。C++中指针使用两个函数应该成对出现那就是new 和 delete。但是autoPtr通过某种方式构造后,无需delete,程序会自动delete。

特性2:指向对象的指针唯一(autoPtr指针所指的对象,只能由唯一指针所指,这点有点难)
C++中可以多个指针同时指向一个对象,但是autoPtr指向对象不能为多个指针同时指。

autoPtr 使用误区:

(1)将autoPtr作为参数

//声明一个函数,autoPtr做参数
function(autoPtr<class1> obj);
//声明一个autoPtr对象
autoPtr<class1> obj1;
//函数调用
function(obj1);
上面调用完后,obj1将不再拥有所指的对象,该对象已经赋给了形参obj,但obj是一个瞬态变量,函数调用完后会自动释放。这是obj1指针变为NULL,无法对采用obj1进行任何操作。否则会出现segmentfault。
(2) autoPtr对象赋值
autoPtr<class1>A=class1:New();//A有指对象
autoPtr<class1> B;//B没有对象可指
B=A;//将A指对象给B,注意是给不是复制。
这时候,B将指向A原来指的对象,A指针变为空。
(3)将autoPtr指针付给其他标准指针
autoPtr<class1> A=class1:New();
class1 *B;
B=A.ptr();
上面操作结束后A指针变空,B标准指针指向A原来对象,这时候B使用结束后应该释放B所指对象,否则会出现内存漏洞。 释放B就直接delete B; 就行了。

并不是说,autoPtr对象就不能传递数据了,传递数据时候请采用引用。
如: autoPtr<class1> A;
const class1 & B=A(); //注意A后面的()为取引用的意思。
这样操作,不会将A所指的对象释放掉,对A所指对象的操作,就可以通过B来完成了。这点很重要,特别是openfoam中很多动态创建对象都是通过autoPtr来完成的。如果在类中声明了autoPtr,可以通过上述方式将类里面的对象传出来。

转自OpenFOAM研究:http://blog.sina.com.cn/openfoamresearch
页: [1]
查看完整版本: [转贴]OpenFOAM中的智能指针autoPtr