使用前向声明和虚函数时遇到问题。我在编译期间收到以下错误消息。
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 :(得分:3)
由于前向声明编译器正在全局命名空间中查找类QueryResult
。您在类MySQL
中定义的函数使用内部类(在命名空间内)QueryResult
。这被编译器视为重载,而不是纯虚函数的实现。我解决这个问题的建议是删除前向声明并使QueryResult
成为接口Interface
的内部类(将它放在那里是有意义的,否则没有使用接口)。然后它将正确编译。
答案 1 :(得分:1)
将decl“QueryResult”移动到名称空间Database :: Interface
中似乎是名称空间的问题。
答案 2 :(得分: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;
};