2010-08-10 185 views
2

我有使用前向聲明和虛函數的問題。編譯期間我收到以下錯誤消息。C++前向聲明和純虛函數

main.cpp:131: error: cannot allocate an object of abstract type ‘Database::MySQL’ 
database_mysql.h:31: note: because the following virtual functions are pure within ‘Database::MySQL’: 
database.h:28: note: virtual void Database::Interface::query(const char*, QueryResult&) 
database.h:29: note: virtual void Database::Interface::query(std::string, QueryResult&) 
database.h:30: note: virtual bool Database::Interface::step(QueryResult&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) 

編譯器說這些函數仍然是純虛函數,但是我正確地聲明和定義了它們。我不知道問題是什麼。

這是我的源代碼。

// database.h 
class QueryResult; 

namespace Database 
{ 
    class Interface { 
     public: 
      Interface() {}; 
      virtual ~Interface() {}; 

      virtual void query(const char *sql) = 0; 
      virtual void query(std::string sql) = 0; 
      virtual void query(const char *sql, QueryResult &result) = 0; 
      virtual void query(std::string sql, QueryResult &result) = 0; 
      virtual bool step(QueryResult &result, 
           std::vector<std::string> &row) = 0; 
    }; 
} 

// database_mysql.h 
namespace Database 
{ 
    class MySQL : public Interface { 
     public: 
      class QueryResult { 
      public: 
       QueryResult(); 
       ~QueryResult() ; 
       void set(MYSQL_RES *result); 
       MYSQL_RES *get(); 

      private: 
       MYSQL_RES *_result; 

      }; 

      ... 

      void query(const char *sql); 
      void query(std::string sql); 
      void query(const char *sql, QueryResult &result); 
      void query(std::string sql, QueryResult &result); 
      bool step(QueryResult &result, std::vector<std::string> &row); 

      ... 
    }; 
} 


// database_mysql.cpp 
Database::MySQL::QueryResult::QueryResult() 
    : _result(NULL) 
{ 
} 

Database::MySQL::QueryResult::~QueryResult() 
{ 
    ... 
} 

void Database::MySQL::QueryResult::set(MYSQL_RES *result) 
{ 
    ... 
} 

MYSQL_RES *Database::MySQL::QueryResult::get() 
{ 
    ... 
} 


void Database::MySQL::query(const char *sql) 
{ 
    ... 
} 

void Database::MySQL::query(std::string sql) 
{ 
    ... 
} 

void Database::MySQL::query(const char *sql, QueryResult &result) 
{ 
    ... 
} 

void Database::MySQL::query(std::string sql, QueryResult &result) 
{ 
    ... 
} 

/* @return: false on done or true if remained rows exist */ 
bool Database::MySQL::step(QueryResult &result, std::vector<std::string> &row) 
{ 
    ... 
} 

謝謝。

+0

您必須顯示main.cpp中的內容:131,以便我們可以爲您提供幫助。您的具體類是正確定義的,但我懷疑您沒有正確實例化對象。 另外,正如@anders指出的那樣,您的QueryResult類應該屬於Interface.h文件。 – 2010-08-10 04:57:05

+0

@Edison Gustavo Muenz:這個錯誤可以通過嘗試創建一個'Database :: MySQL'類的實例來複制。 – Naveen 2010-08-10 05:11:13

回答

1

招DECL「QueryResult中」變成了命名空間數據庫::接口

它似乎是一個名字空間的問題。

+0

感謝您的回覆。但是,這個問題仍然存在相同的錯誤消息。 – Brian 2010-08-10 05:04:56

3

由於前向聲明編譯器正在全局命名空間中尋找類QueryResult。您在類MySQL中定義的函數使用內部類(位於名稱空間內)QueryResult。這被編碼器視爲重載,而不是作爲純虛函數的實現。我建議解決這個問題是刪除前向聲明,並使QueryResult爲接口Interface的內部類(將它放在那裏是有意義的,否則就不會使用該接口)。然後它會正確編譯。

+0

謝謝。嗯...我使用前向聲明,以使不同的QueryResult類依賴於SQL API,如database_sqlite3.h等,但我認爲這是不可能的,如果我把QueryResult類放入Interface類。 – Brian 2010-08-10 05:17:51

+0

也許你可以使'QueryResult'也是一個抽象基類,這樣'Interface'的不同實現可以提供它們自己的'QueryResult'實現? – Naveen 2010-08-10 05:23:50

+0

謝謝,我現在就試試看,但是我怎樣才能在抽象基類的成員函數參數中收到不同的數據庫句柄?我應該使用void指針還是模板類?對不起,我的可憐的問題。我是C++新手。 :-) – Brian 2010-08-10 05:38:22

0

現在可以通過將QueryResult作爲類並從中得到MySQLQueryResult來快速修復。正如其他人指出的那樣,問題在於編譯器無法使用嵌套類而不是前向聲明類。

 // database.h 
     class QueryResult { 
     //make this class abstract by creating a protected default constructor 
     protected: 
      QueryResult(){} 
     } 

     //mysql.cpp 
     class QueryResult : ::QueryResult { 
     public: 
      QueryResult(); 
      ~QueryResult() ; 
      void set(MYSQL_RES *result); 
      MYSQL_RES *get(); 

     private: 
      MYSQL_RES *_result; 

     }; 
+0

是否可以使用QueryResult引用調用MySQLQueryResult的函數?如何在接口的成員函數上聲明MySQLQueryResult參數而不進行前向聲明? – Brian 2010-08-10 06:34:39

+0

你的'QueryResult'基類應該包含適用於'Interface'所有實現的成員,所以'QueryResult'應該包含最小公分母函數/屬性。 – 2010-08-10 06:39:30