C++前向声明和纯虚函数

发布于 2024-09-13 10:16:42 字数 2855 浏览 2 评论 0原文

我在使用前向声明和虚函数时遇到问题。我在编译过程中收到以下错误消息。

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

谢谢。

I have a problem using forward declaration and virtual functions. I got the following error message during compilation.

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> > > >&)

The compiler said these functions are still pure virtual functions, but I declared and defined them properly. I don't know what the problem is.

Here is my source code.

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

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

z祗昰~ 2024-09-20 10:16:42

由于前向声明,编译器正在全局命名空间中查找类QueryResult。您在 MySQL 类中定义的函数使用内部类(位于命名空间内)QueryResult。这被编译器视为重载,而不是纯虚函数的实现。我解决这个问题的建议是删除前向声明,并使 QueryResult 成为接口 Interface 的内部类(将它放在那里是有意义的,否则没有用接口)。然后就可以正确编译了。

Because of the forward declaration compiler is looking for the class QueryResult in the global namespace. The function you defined in class MySQL use the inner class (which is inside the namespace) QueryResult. This is treated as an overloading by the compiler and not as the implementation of the pure virtual function. My suggestion to solve this is to remove the forward declaration and make the QueryResult a inner class of interface Interface (it makes sense to put it there, otherwise there is no use of the interface). Then it will compile properly.

翻身的咸鱼 2024-09-20 10:16:42

将 decl“QueryResult”移到名称空间 Database::Interface 中,

这似乎是名称空间的问题。

move the decl "QueryResult" into the namespace Database::Interface

it seems to be an issue with name spaces.

素衣风尘叹 2024-09-20 10:16:42

您现在可以通过将 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;

        };

You can probably do a quick fix now by making QueryResult a class and deriving MySQLQueryResult from it. As others pointed out the issue is with compiler not being able to use a nested class instead of the forward declared class.

        // 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;

        };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文