2

前方宣言と仮想関数の使用に問題があります。コンパイル中に次のエラー メッセージが表示されました。

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)
{
    ...
}

ありがとうございました。

4

3 に答える 3

3

QueryResult前方宣言のため、コンパイラはグローバル名前空間でクラスを探します。クラスで定義した関数はMySQL、内部クラス (名前空間内) を使用しますQueryResult。これは、純粋仮想関数の実装としてではなく、コンパイラによってオーバーロードとして扱われます。これを解決するための私の提案は、前方宣言を削除し、QueryResultインターフェイスの内部クラスにすることですInterface(そこに配置することは理にかなっています。そうしないと、インターフェイスは使用されません)。その後、正常にコンパイルされます。

于 2010-08-10T05:06:00.547 に答える
1

Decl "QueryResult" を名前空間 Database::Interface に移動します

名前空間に問題があるようです。

于 2010-08-10T04:57:27.603 に答える
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;

        };
于 2010-08-10T06:18:57.917 に答える