SOUI中对象的生命周期管理
C++程序员最难的一环就是处理内存泄漏。
很多情况下,一个对象在一个模块里分配了内存,忘记了释放,或者在另一个模块里释放都会导致内存相关的问题。
SOUI中大部分暴露在应用层的对象都使用类似COM的引用计数来管理对象的生命周期,包含SWindow, ISkin, EventArg, SStringT, IRenderTarget, IBitmap, IAdapter以及各种扩展组件。
SOUI中引用计数的基类是:SOUI::IObfRef
namespace SOUI
{
struct IObjRef
{
virtual long AddRef() PURE; virtual long Release() PURE; virtual void OnFinalRelease() PURE;
};
}
SOUI中使用引用计数有一个简单的原则:一个对象,谁AddRef,那也应该它来Release。
经常有人问:为什么我调用了SImageWnd::SetImage就有内存泄漏了?
用户的代码可能是下面这样的:
bool SDemoSkin::SetImage(SStringW imgfile)
{
m_bIsColor = false;
m_FilePath = imgfile;
IBitmap *image = LOADIMAGE2(L"file:" + imgfile);
if (image)
{
SetImage(image);
//image->Release();
return true;
}
return false;
}
这个问题很简单,看一下SetImage(IBitmap*)这个方法的代码就知道,它会自己持有这个IBitmap*对象。
通常这是用户从文件或者内存加载后创建的IBitmap对象,所有SOUI对象的创建都自动调用了AddRef,因此调用它个方法的人调用完成后,不再使用这个对象,则应该相应的调用一下Release(即打开代码中被注释的行)。
SOUI中也提供了一个智能指针来简化这个引用计数的操作:SAutoRefPtr (2.x是CAutoRefPtr)
使用智能指针,上面代码可以改写为:
bool SDemoSkin::SetImage(SStringW imgfile)
{
m_bIsColor = false;
m_FilePath = imgfile;
SAutoRefPtr<IBitmap> image;
image.Attach(LOADIMAGE2(L"file:" + imgfile));
if (image)
{
SetImage(image);
return true;
}
return false;
}
注:由于LOADIMAGE2内部已经调用了AddRef,而智能指针直接赋值时会自动AddRef,因此这里要用image.Attach来获得指针。Attach不会自动调用AddRef.
使用好IObjRef,配合上SAutoRefPtr,可以将SOUI的内存泄漏问题降低很多。
启程软件 2019年10月17日
SOUI中对象的生命周期管理的更多相关文章
- java之hibernate之session中对象的生命周期
1. session是用来执行对象的crud操作,并且session是对象事务工厂.session是线程级别的,所以生命周期比较短. 2.session中对象的生命周期图: 3.session中对象的 ...
- Tomcat中组件的生命周期管理公共接口Lifecycle
Tomcat的组件都会实现一个Lifecycle接口,以方便组件的生命周期的统一管理 interface Lifecycle 组件生命周期中主要的几个方法 增加监听器,事件委托机制 public vo ...
- 第四章 Spring.Net 如何管理您的类___对象的生命周期链
各位,实在不好意思,因为有事,博客几天没更新了.前面有童鞋提到,配置 Objects.xml 路径的相关问题,这些东西是 IResource 接口的一些内容.在下一章会详细介绍. 传统的Net应用中, ...
- 依赖注入及AOP简述(十一)——生命周期管理 .
2. 生命周期管理 各种依赖注入框架提供了替开发者管理各种Scope的便利功能,随之而来的就必然是被管理的依赖对象的生命周期管理的问题.所谓生命周期管理,就是一个对象在它所属的Scope中从被 ...
- ElasticSearch——索引生命周期管理
从ES6.6开始,Elasticsearch提供索引生命周期管理功能,索引生命周期管理可以通过API或者kibana界面配置,详情参考[index-lifecycle-management] 本文仅通 ...
- Elasticsearch索引生命周期管理探索
文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484130&idx=1&sn=454f199 ...
- ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理
ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...
- [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Delphi 接口使用中,对象生命周期管理,如何释放需要注意的问题
网上有篇文章<Delphi接口编程的两大陷阱>,里面提到接口的生存期管理的问题.但该文章里面提到的两个问题,其实都是对 Delphi 不理解导致的. 先说该篇文章中提到的第一个问题为什 ...
随机推荐
- qt QAbstractItemModel一些方法介绍
一. virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::Edit ...
- Qualcomm_Mobile_OpenCL.pdf 翻译-4-Adreno OpenCL的程序开发
这章将简要讨论一些开发Adreno OpenCL应用程序的基本要求,下面将会介绍如何调试和统计程序性能. 4.1 安卓平台上开发OpenCL程序 目前,Adreno GPU主要是在安卓操作系统和在部 ...
- java数据结构03
1.求二叉树的深度 https://www.cnblogs.com/xudong-bupt/p/4036190.html class TreeNode { char val; TreeNode lef ...
- hdu 3549 网络流最大流 Ford-Fulkerson
Ford-Fulkerson方法依赖于三种重要思想,这三个思想就是:残留网络,增广路径和割. Ford-Fulkerson方法是一种迭代的方法.开始时,对所有的u,v∈V有f(u,v)=0,即初始状态 ...
- 深入理解JAVA虚拟机 虚拟机执行子系统
class类文件的结构 java的class类文件中存在两种结构:无符号数和表.最小的存储单元是8个字节. 无符号数是基本的数据类型,用来描述数字,UTF-8编码的字符串,索引引用. 表示多个无符号数 ...
- Spring Boot JPA - Querydsl
https://lufficc.com/blog/spring-boot-jpa-querydsl
- java课堂动手测试
课堂实验3 一个Java类文件中真的只能有一个公有类吗? 经过测试,当含有两个public 类时会报错,不能执行,假如删除第二个public则可以正常生成,说明一个java文件只能有一个公有类. 课 ...
- C的随机数用法
rand() #include <stdio.h> #include <stdlib.h> int main() { ; i < ; i++) { printf(&quo ...
- node 的CommonJS的引入
1.CommonJS 每个文件是一个模块,有自己的作用域 引入:
- String,Integer,int类型之间的相互转换
String, Integer, int 三种类型之间可以两两进行转换 1. 基本数据类型到包装数据类型的转换 int -> Integer (两种方法) Integer it1 = new I ...