C++静态变量对象的建立和删除,兼论MFC开始运行的起点(全局对象)
看了不少C++书,当讲到静态变量的时候,总是以int成员来举例,是啊,这样很好理解。但是如果这个静态变量是一个对象行不行呢?不仅行,有时候还非常必要,而且别有洞天。
比如:
// .h 文件
class SystemGlobal
{
public:
static ConfigXML* m_pInstance;
}
// .cpp 文件
ConfigXML* SystemGlobal::m_pInstance = new ConfigXML();
SystemGlobal::SystemGlobal(void)
{
}
那么应该何时删除这个对象呢?想了很久,一开始觉得应该是在main()函数里,我这是还是QT程序,不得不改写了main()函数通常的return 方式,变成这样:
MainWidget main_widget;
main_widget.showWidget(); int ret = app.exec();
delete SystemGlobal::m_pInstance;
return ret;
我试了试,程序可以正常退出。反正我试了5遍都没有问题。普通C++程序没有app.exec的困扰,应该更加没有问题。
---------------------------------------------------------
然后我又在网上搜了搜(很难搜到啊),受这个帖子启发:
http://bbs.csdn.net/topics/200006181
改成在拥有静态变量对象的类析构函数里删除它,如下:
SystemGlobal::~SystemGlobal(void)
{
delete SystemGlobal::m_pInstance;
}
同样试了5次,也没有问题。
但是我觉得这种方法不好,因为万一SystemGlobal在整个项目中有多个实例呢,难道销毁一个实例的时候,就必须销毁这个静态对象?这种方法只适合于整个项目就这一个SystemGlobal实例的情况。而且析构函数不允许重载和参数,就显得更加有问题了。
---------------------------------------------------------
最后要提一句,静态变量对象的初始化不仅仅别有洞天,而且实际上是相当重要的,因为它会在main()函数开始前执行,这代表什么?代表在main()函数的第一句语句执行之前,已经执行过这个静态变量对应的类的构造函数了,而构造函数本身可以执行无穷无尽的语句,相当于main()函数只是一个正房,在正房出现前,程序员已经与小三天翻地覆一番后才回来了(真是经典案例!),而且这个小三仍存在于内存之中,与正房并列。
不要奇怪,其实MFC的执行流程就是从CMyApp(继承于CWinApp)的theApp实例生成的过程开始的(注意,theApp不是静态变量对象,但却是一个写在.cpp文件中的全局对象,其实与静态变量对象也没有什么本质的区别,也正因为theApp对象的指针仍需要被获取,但又没有静态变量那么方便,所以微软专门提供了AfxGetApp()全局函数。但是为什么提供这个函数,而不是使用静态变量对象呢?我觉得2个原因,1是静态变量名称又臭又长,2是函数具有更好的封装性,可以做更多的检查乃至偷天换日):
MyApp::MyApp()
{ // 断点2,在括号这行下断点
} MyApp theApp; // 断点1,在这行也下断点 BOOL MyApp::InitInstance()
{
}
// 断点3,手动打开appmodul.cpp文件,然后在_tWinMain的括号处下断点
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,__in LPTSTR lpCmdLine, int nCmdShow)
{
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
执行,通过追踪MFC源代码,可以发现程序首先定位于断点1,按F11追踪,发现会落在断点2。继续按F11,会发现执行CWinApp::CWinApp(LPCTSTR lpszAppName),然后按F10,发现会执行一大堆语句才会返回。可见的确实别有洞天。做完这些事情以后,就开始执行WinMain函数了(断点3),具体可以发现WinMain函数是在appmodul.cpp文件中。
读书笔记,两种效果:1. 在MFC初始化完成后,WinMain被自动调用,两者就相互联系起来了 2. MFC没有也不可能封装WinMain函数(有待进一步阐述)
参考:
http://www.cnblogs.com/zhili/p/mfcanalyze.html
http://www.moon-soft.com/program/bbs/readelite9623.htm
http://www.cnblogs.com/suncoolcat/p/3367627.html
http://www.xuebuyuan.com/2119787.html (彩色贴图,比较清楚)
http://cnmqw.iteye.com/blog/1921782 (精简了代码,非常清楚)
C++静态变量对象的建立和删除,兼论MFC开始运行的起点(全局对象)的更多相关文章
- 全局对象Application的使用,以及如何在任何地方得到Application全局对象
Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个application对象,用来存储系统的一些信息.通常我们是不 ...
- Java 局部变量、实例变量、类变量(静态变量)区别
1. 局部变量: 局部变量是类的方法中的变量: 2. 实例变量: 实例变量也是类中独立于方法之外的变量,不过没有static修饰,也叫 对象变量 3. 类变量(静态变量): 类变量是类中独立于方法之外 ...
- [ 转载 ]Java:成员变量,局部变量,静态变量的区别
精简后方便自己理解. 成员变量 我们研究一个事物: 属性:外在特征:如身高,体重 行为:能做什么:如说话,打球. 在Java语言中,最基本的单位是类(class),类就是用来体现事物的. 属性:类中的 ...
- 1.7Oob 静态变量静态方法
1)静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员 2)如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量. 3)静态方法中不能直接调用非静态方法 ...
- 成员变量(实例变量)&局部变量&静态变量(类变量)的区别
成员变量(实例变量)&局部变量区别: (1)作用域 成员变量:针对整个类有效. 局部变量:只在某个范围内有效.(一般指的就是方法,语句体内) (2)存储位置 成员变量:随着对象的创建而存在,随 ...
- 谈谈java中静态变量与静态方法在有继承关系的两个类中调用
谈谈java中静态变量与静态方法在有继承关系的两个类中调用 学习的中如果遇到不明白或者不清楚的的时候,就是自己做些测试,自己去试试,这次我就做一个关于静态变量和静态方法在有继承关系的两个类中的问题测试 ...
- java 静态变量&静态方法
1. 静态变量是static修饰的成员变量(类变量),若无static修饰,则是实例变量.静态变量是一种全局变量,它属于某个类,不属于某个对象实例,是在各对象实例间共存. 访问静态变量直接通过类名 ...
- JavaScript中hoisting(悬置/置顶解析/预解析) 实例解释,全局对象,隐含的全局概念
JavaScript中hoisting(悬置/置顶解析/预解析) 实例解释,全局对象,隐含的全局概念 <html> <body> <script type="t ...
- JavaScript 全局对象
全局属性和函数可用于所有内建的 JavaScript 对象. 顶层函数(全局函数) 函数 描述 decodeURI() 解码某个编码的 URI. decodeURIComponent() 解码一个编码 ...
随机推荐
- Java json设置时间格式,Jackson设置时间格式,json设置单引号
Java json设置时间格式,Jackson设置时间格式,json设置单引号 >>>>>>>>>>>>>>> ...
- php中的全局变量引用
全局变量在函数外部定义,作用域为从变量定义处开始,到本程序文件的末尾.但和其他语言不同,php的全局变量不是自动设为可用的,在php中函数可以视为单独的程序片段,局部变量会覆盖全局变量的能见度,因此, ...
- Unity3D 之3D游戏角色控制器运动
3D运动,绑定了人形控制器后的一个简单的运动方法. using UnityEngine; using System.Collections; public class PlayerMove : Mon ...
- 学习笔记_Java_day13_JSTL标签库(1、2、3、4、5、6、7、8)
1.一种标签语言 day13 l JSTL标签库(重点) l 自定义标签(理解) l MVC设计模式(重点中的重点) l Java三层框架(重点中的重点) JSTL标签库 1 什么是JSTL ...
- selenium IDE处理各种窗口问题解决方法
一.处理模态窗口:showModalDialog 由于弹出模态窗口后,就无法定位到当前窗口的元素和模态窗口的元素,需要添加js解决 模态窗口动作类似下面语句: <input id="c ...
- 巧谈 GCD
转载自:http://www.jianshu.com/p/665261814e24 谈到iOS多线程,一般都会谈到四种方式:pthread.NSThread.GCD和NSOperation.其中,苹果 ...
- java新手笔记10 构造器
1.摇奖小程序 package com.yfs.javase; import java.io.IOException; import java.nio.CharBuffer; import java. ...
- ellang 中进程异步通信中的信箱与保序
erlang 进程通讯中 执行到 receive 语句时 如果信箱没有消息可以匹配时会暂停等待消息. go() -> register(echo, spawn(test_pid,loop,[]) ...
- Asp.net创建伪静态页面
下面是我研究了好几天和同事一起才研究出来的,原创. 1伪静态的定义: 伪静态是相对真实静态来讲的,通常我们为了增强搜索引擎的友好面,都将文章内容生成静态页面,但是有的朋友为了实时的显示一些信息.或者还 ...
- wdcp日志
apache或nginx都有开关默认日志,一个是正常访问日志,一个是错误的日志,目录在 /www/wdlinux/nginx-1.0.15/logs /www/wdlinux/httpd-2.2.22 ...