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 回答