4

我正在尝试使用 libpqxx 库开发一个非常简单直接的连接池。我对 c++ 还是很陌生,仍然对指针和引用感到很困惑。该类的行为非常简单:拥有一个带有一些已初始化连接的向量,并在需要时将连接弹出并推送到该向量上。由于指针和引用的错误实现,代码有很多错误。你能给我一些提示吗?

编辑:我设法修复了所有编译错误。当我运行主要功能时,它给了我一个分段错误。

class DbPool {

上市:

pqxx::result runQuery(const string& query) {

    connection *conn = getCon();
    work trans(*conn);
    result res = trans.exec(query);
    trans.commit();
    releaseCon(conn);

    return res;
}

DbPool(uint32_t max_cons) {

    for (uint32_t i = 0; i < max_cons; i++) {

        connection* con = createCon();
        m_freeCons.push_back(shared_ptr < connection > (con));
    }
}

私人的:

connection * createCon() {

    connection * conn =
            new connection(
                    "user='ak' password='rootpassword' dbname='bips_office' hostaddr='127.0.0.1' port='5432'");
    return conn;
}

void releaseCon(connection *con) {

    m_freeCons.push_back(shared_ptr < connection > (con));
}

connection* getCon() {

    shared_ptr < connection > conn = *(m_freeCons.end() - 1);
    m_freeCons.pop_back();
    return conn.get();
}

vector<shared_ptr<connection> > m_freeCons;

};

int main(int argc, char *argv[]) {
     DbPool *pool = new DbPool(5);
     result res = pool->runQuery("SELECT COUNT (*) from captures");
     return 0;
}
4

2 回答 2

2

如果您担心设计问题,这是我的五分钱:

  • 你的代码真的可以编译吗?我认为不是,因为您有一个指向连接的指针向量,但是您正在推回连接对象(m_freeCons.push_back(*con);-*取消引用指向连接的指针)...
  • 向成员提供可修改的句柄通常是一个坏主意(就像您在getCon方法中所做的那样 - 至少,connection const *如果可能,请返回 a
  • 如果您必须使用指针集合,请考虑使用shared_ptr而不是原始指针 - 这样您就不必担心释放内存;或使用Boost.PointerContainer;也见这里
  • 只是一个奇怪的风格问题:你为什么使用return &(*conn)?这会取消引用指针conn,然后再次获取它的地址。相反,你可以简单地写return conn

用 s 回答您重写的问题shared_ptr:您仍然需要使用 new 创建连接,并在其周围包裹一个 shared_ptr;例如对于 createCon:

connection * createCon(){

    connection * conn = new connection("user='ak' password='rootpassword' dbname='bips_office' hostaddr='127.0.0.1' port='5432'");
    return conn;
}

    connection* con = createCon();
    m_freeCons.push_back(shared_ptr<connection>(con));

在其他地方也类似。

于 2012-09-21T10:00:28.947 回答
1

受您帖子的启发,我在自己的项目中使用了这个简单的连接池。我使用了std::stack。推和弹出。添加连接时除了 try-catch 之外没有错误检查。对于 postgresql-db。

数据库.hpp:

#include <stack>
#include <pqxx/pqxx>

class Database {
private:
    const std::string connectionString = "dbname=db user=usr hostaddr=127.0.0.1 port=5432";
    std::stack<pqxx::connection *> dbpool;

public:
    Database(const unsigned int);

数据库.cpp:

#include "Database.hpp"

Database::Database(const unsigned int connections) {
    for (int i = 0; i < connections; ++i) {
        try {
            auto* dbconn = new pqxx::connection(connectionString);
            dbpool.emplace(dbconn);
        } catch (const std::exception& e) {
            std::cerr << e.what() << std::endl;
        }
    }
}

主.cpp:

#include "Database.hpp"

int main(int argc, char* argv[]) {
    Database database {10};

    auto *D = dbpool.top();
    dbpool.pop();

    const std::string query = "select * from mytable";
    pqxx::nontransaction N(*D);
    pqxx::result R(N.exec(query));

    for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) {
        std::cout << c[1].as<std::string>() << std::endl;
    };

    dbpool.push(D);
}
于 2016-01-01T19:41:48.493 回答