我做了一个对话框应用程序,有一个主窗体,三个子窗体。每个窗体程序都需要访问数据库中的数据。我要用_ConnectionPtr m_pConnect和_RecordsetPtr m_pRecordset来实现数据访问的功能!
  我首先在class CTeleApp : public CWinApp{}里声明了一个公共_ConnectionPtr m_pConnect指针,在主窗体的BOOL CTeleDlg::OnInitDialog(){}里实例化,然后分别在每一个子窗体中声明一个_RecordsetPtr m_pRecordset指针并实例化,但为什么当我第二次调用m_pRecordset显示数据时,出现Runtime Error! -Pure virtual function call. 错误?
     
                     我该怎么做?
                                         多谢指教!!

解决方案 »

  1.   

    贴主要代码
    m_pRecordset 已经被你销毁了
      

  2.   

    zhp80(zhp80) 你什么意思呀?能具体说一说吗?
      

  3.   

    在第二次调用前要保证m_pRecordset 已经关闭,如果没关闭,m_pRecordset ->Close();
      

  4.   

    我在子窗体的初始化程序里是这样写的:
    BOOL CCheckFaxFile::OnInitDialog() 
    {
         try
        {
                if(m_pRecordset1!=NULL)
                {
                      m_pRecordset1 = NULL;
                      m_pRecordset1.Release();
                 }
    m_pRecordset1.CreateInstance("ADODB.Recordset");
    m_pRecordset1->Open(_T("SELECT * FROM FAXFILE"),_variant_t((IDispatch*)theApp.m_pConnect,true),adOpenStatic,adLockOptimistic,adCmdText);
    }
       catch(_com_error e)///捕捉异常
    {
    AfxMessageBox("读取数据库失败!");///显示错误信息
    m_pRecordset1->Close();
    }
    }
       但还是出Runtime Error! -Pure virtual function call错!
                 
                  我该怎么办??顶!!
      

  5.   

    m_pRecordset1.Release();
    要放在NULL之前!否则的话,NULL怎么Release?或者不用 m_pRecordset1.Release();,只用Close和赋空就可以了,智能指针自动释放
      

  6.   

    我把m_pRecordset1.Release();去掉了,但还是出错!
       
       我的目的就是想建立一个公共的连接_ConnectionPtr m_pConnect,在多个类中调用它,我在每个类中创建了一个_RecordsetPtr m_pRecordset,第一次运行显示没问题,但当我第二次再运行时就出错了。
       请问是什么原因?
      

  7.   

    按照楼主的意思就是现在App里面建立公共的_ConnectionPtr
    HRESULT hRes;
    try
    {
       hRes=m_pConnection.CreateInstance(_T("ADODB.Connection"));
       m_pConnection->ConnectionTimeout = 8;
       hRes=m_pConnection->Open(_bstr_t((LPCTSTR) ConnectString),
                _T(""),_T(""),adModeUnknown);
    }
    catch(_com_error e)
    {
       return FALSE;
    }
    然后在你需要调用_RecordSetPtr的函数里面写
    try
    {
         HRESULT hTRes;
         hTRes = m_pRecordset.CreateInstance(_T("ADODB.Recordset"));
         if (SUCCEEDED(hTRes))
         {
    _variant_t vConn;
    vConn=(IDispatch *)(((CXXXApp*)AfxGetApp())->m_pConnection);
    //----------------------------------------------------
    hTRes = m_pRecordset->Open((LPCSTR)strSQL,vConn,
    adOpenDynamic, adLockPessimistic,
          adCmdText);
         if(SUCCEEDED(hTRes))
         {
             
          }
    catch(_com_error e)
    {
          .......
    }
    这样应该没问题了,你试试吧,有问题再讨论

     
      

  8.   

    对不起,我刚才出去了一下!
    调试的时候是在:
    m_pRecordset1->Open(_T("SELECT * FROM FAXFILE"),_variant_t((IDispatch*)theApp.m_pConnect,true),adOpenStatic,adLockOptimistic,adCmdText);
    出错。
      

  9.   

    up
    如果你想在各个类中使用,可以在APP或是主框架函数中定义_ConnectionPtr m_pConnect,
    然后在初始化中连接服务器,这样使用时通过指针调用,通过结果集_RecordsetPtr m_pRecordset来完成SQL语句!具体代码可以去www.vckbase.com上查找!
      

  10.   

    csdmy(在郁闷中不停的努力)   你好!
      我用你的方法,为什么((CXXXApp*)AfxGetApp())里面没有m_pConnection成员变量呢?我是在下面的地方声明的:class CTeleApp : public CWinApp
    {
    public:
    CTeleApp();
    _ConnectionPtr m_pConnect;
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CTeleApp)
    public:
    virtual BOOL InitInstance();
    virtual int ExitInstance();
    //}}AFX_VIRTUAL// Implementation //{{AFX_MSG(CTeleApp)
    // NOTE - the ClassWizard will add and remove member functions here.
    //    DO NOT EDIT what you see in these blocks of generated code !
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    private:
    BOOL m_bATLInited;
    private:
    BOOL InitATL();
    };
    然后在我的主程序BOOL CTeleDlg::OnInitDialog(){}里面实例化的:
    HRESULT hr;
    try
    { hr = theApp.m_pConnect.CreateInstance(__uuidof(Connection));///创建Connection对象
    ::CoInitialize( NULL );
    theApp.m_pConnect->PutCursorLocation(adUseClient);
    if(SUCCEEDED(hr))
    {
    hr = theApp.m_pConnect->Open("Provider=OraOLEDB.Oracle.1;Persist Security Info=False;User ID=scott;Data Source=linkpro","scott","tiger",adModeUnknown);///连接数据库
    }
    }
    catch(_com_error e)///捕捉异常
    {
    CString errormessage;
    errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());
    AfxMessageBox(errormessage); //显示错误信息
    }
      

  11.   


    ::CoInitialize( NULL );
    hr = theApp.m_pConnect.CreateInstance(__uuidof(Connection));//
    有一定的顺序。
    ::CoInitialize( NULL );// 最好是在 C--APP 中初始化。贴一段我的代码:
    我是在CMyListView 中声名的
    void CMyListView::OnInitialUpdate() 
    {
    CListView::OnInitialUpdate();

    // TODO: Add your specialized code here and/or call the base class
    ::CoInitialize(NULL);
    HRESULT hr;
    _bstr_t source("Data Source=sdcg;UID=;PWD=");
        try{
    hr=m_connection.CreateInstance(_uuidof(Connection));
    if(SUCCEEDED(hr))
    hr = m_connection->Open(source,"","",adModeUnknown);///连接数据库
    if(SUCCEEDED(hr))
    hr=m_recordset.CreateInstance(_uuidof(Recordset));
    if(SUCCEEDED(hr))
    m_fConnected=true;
    else
    m_fConnected=false;
    }
    catch(_com_error &e){
    MessageBox(e.ErrorMessage());
    m_fConnected=false;
    }
    if(!m_fConnected)MessageBox("ADO 数据源初始化失败!");
    else m_strSource=(const char *)source;
    ////////////////////////////////////////////// CListCtrl &m_ListCtrl=(CListCtrl&)GetListCtrl();
    m_ListCtrl.ModifyStyle(LVS_LIST,LVS_REPORT);}