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

  • 相关阅读:
    oracle 存储过程 技巧
    任何用户密码都能以sysdba角色登入
    DBA操作常用命令
    事务 脏数据
    Axis2 WebService(配置、发布、调用)
    C#接口
    纯CSS3实现的一些酷炫效果
    C#运算符大全_各种运算符号的概述及作用
    mvc图片上传到服务器
    C# .NET 基本概念
  • 原文地址:https://www.cnblogs.com/guobbs/p/3889628.html
Copyright © 2020-2023  润新知