学习openCV的过程中,出于程序员的习惯,对于内存管理策略做了一些整理和分析,总结如下:
1.关于vector<>
由于vector<>是用来保存动态数据的最常用的class,所以做了一些整理,相信这些内存管理规则也会适用于其他std的内置容器类,比如set dequeue list map等等。
查了一下vector<>,只要存的是对象或简单类型,就不用操心,vector自己释放的时候会把其中的对象或简单类型都释放掉,更好的是,vector作为对象创建,到了作用域结束,也会自动释放,因为这个原因,opencv的方法都是要求把vector作为引用传入,就不用考虑释放的问题了,如果在方法中创建对象,就不能return出去,因为方法结束,对象自动释放,如果在方法中new 或malloc,就需要调用方法的代码负责delete 或 free;相比之下,还是在调用方法的代码中创建对象,然后传引用给方法,这个策略最好,这样一来就完全不用特意考虑对象释放的问题了;同理,vector也基本不会存指针,因为也要显式释放
2. 使用引用(reference &)
在把创建好的对象传入方法的时候都用引用.
在函数中,如果要用一个已经创建好的对象,比如vector<>中的对象,最好不用指针,而是用引用,从使用角度,指针和引用没区别,但是,从代码可读性角度来说,可以形成一个习惯:凡是指针都是new 或 malloc生成的,而且需要delete或free,引用和一般对象看起来的形象是一致的,都可以认为是无需关心内存释放的问题。简单一句话:凡是指针都要负责释放,凡是引用或一般对象都不用管释放。
3. vector push_back一个对象,究竟发生了什么?
还是会重新构造一个对象,copy内容进去,也就是说,这个机制相比传指针,还是有开销的。但是好处是,vector中的对象会随着vector析构而析构。具体参考: https://blog.csdn.net/WJSZMD/article/details/79629184
https://www.jianshu.com/p/f5d48a7f5a52
4. 关于Ptr的一些说明
这个类似于智能指针,会维护一个计数器,计数器归零,自动释放对象;这个计数器就是Ptr对象中的一个int*指向的int;这个计数器的增减用的是CV_XADD宏,这个宏实现了线程锁,即使多个线程同时操作计数器也是安全的;具体参考: https://www.cnblogs.com/liu-jun/archive/2013/03/24/2979648.html
https://blog.csdn.net/artista/article/details/48783347
大学时就学过C++,做过数据结构课程的习题,后来用C++开发过VESA总线的驱动,dos下的RTS游戏,做过DOS下的窗口系统,还用MFC开发过一个图片服务器ImageServer,之后就一直用的是asp,java,.net这些语言,这次学习openCV,发现C++也在不断进化,形成了一些内存管理的编程习惯,还有智能指针这样的工具,按照这样的规范,使用这些工具,以及std的内置容器类,现在开发C++程序,就不容易出现内存相关的bug了,至少比当初用Objective-C开发IOS App更规范,后者的内存管理相对原始,也不近完善。