首页 > 代码库 > C++旧源码向新标准移植陷井(一)_局部栈变量的生命周期

C++旧源码向新标准移植陷井(一)_局部栈变量的生命周期

之前在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对像,完美解决此问题.