之前在VC++6.0上面写了下面这样的代码:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; //不重要的部分略过if (argc>1) {if (strcmp(argv[1],"createpcsstep") == 0) { CDlgCreateStepPcs dlg; dlg.DoModal(); break; } else if (strcmp(argv[1],"clearunless") == 0) { CDlgClearUnless dlg; dlg.DoModal(); break; } //还有很多这样的弹对话框,都省略了吧,只留两个else {} } } return nRetCode; }
很明显这是一个控制台程序,启动根据条件判断弹出一个对话框,这段代码在VC6.0中编译,运行无任何问题;
后来照这个代码流程移植成VS2008 + QT sdk重新编译,发现对话框是一闪而过,想了好久,硬是不知道问题出在哪里,可把我郁闷的够呛,经过多次的把代码移动试验,突然想到是变量的生命周期问题,想到这点就豁然开朗了,VS2008使用了新的C++标准,在新标准中C++规定{}中的变量只在这个块中有效,出了块就被析构了(类是被析构),因此Qt中正确的代码顺序是这样的:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QDialog *pDlg = NULL; //新的C++标准中,不能在if块中声明对像,否则出了块就被析构了 if (argc > 1) { if (strcmp(argv[1],_SCRIPTS_NAME_OUTPUTGERBER) == 0) { pDlg = new DlgOutputGerber; pDlg->show(); //造成问题的关键在这里,不同于MFC,这里执行完了还要继续向下进入到a.exec()消息循环 } } int nRet = a.exec(); if (pDlg != NULL) delete pDlg; return nRet; }
见上面的所述的关键点,如果是像前面那样在if块里面声明一个Dialog对像,show()完之后就要出块进入a.exec(),但这样一旦出块,Dialog对像就已经被析构了,因些窗口一闪而过.
我在这里采用的方法是,块外面定义一个指针,if块里面在堆上实例化一个Dialog对像,完美解决此问题.
C++旧源码向新标准移植陷井(一)_局部栈变量的生命周期
时间: 2024-10-06 09:31:14