2011-11-03 194 views
2

我想提出一個包裝爲我用的數據庫,採用波科::數據庫:: ODBCC++類成員初始化(POCO)

正常的代碼應該是這樣的:

Poco::Data::ODBC::Connector::registerConnector(); 
Session ses("ODBC", "DSN=mytest;Uid=mytest;Pwd=mytest"); 
bool bConnected = ses.isConnected(); 
Statement select(ses); 
select << "SELECT firstname FROM Patients", range(0, 10); 
RecordSet rs(select); 
while (!select.done()) 
{ 
    select.execute(); 
    bool more = rs.moveFirst(); 
    while (more) 
    { 
     for (std::size_t col = 0; col < rs.columnCount(); ++col) 
     { 
      std::cout << rs[col].convert<std::string>() << " "; 
     } 
     std::cout << std::endl; 
     more = rs.moveNext(); 
    } 
} 

Poco::Data::ODBC::Connector::unregisterConnector(); 

這工作得很好。

現在對於我的課

class database{ 
    Session ses; //Since this is needed all for all the queries. 
    public: 
    database():ses("ODBC", "DSN=name;uid=user;pwd=pass"){ 
    } 
};//end class 

我如何的ses

初始化調用之前調用Poco::Data::ODBC::Connector::registerConnector()我試圖

database():Poco::Data::ODBC::Connector::registerConnector(),ses("ODBC", "DSN=name;uid=user;pwd=pass"){ 
} 

但這並不適用。它提供了錯誤

'registerConnector' : is not a member of 'Poco::Data::ODBC::Connector'

我應該怎麼辦呢?

回答

4

要麼在database::database()以外,要麼使用指向Session而不是成員的指針,並將其分配到構造函數中的堆上。例如:

database::database() 
{ 
    Poco::Data::ODBC::Connector::registerConnector(); 
    ses = new Session("ODBC", "DSN=name;uid=user;pwd=pass"); 
} 

database::~database() 
{ 
    delete ses; 
} 
+0

'ses'用於像'ses <<「SELECT COUNT(*)FROM customer」這樣的語句,進入(count),now;',我早些時候試過這種方法,但是這些語句給出了錯誤。 – Pheonix

+0

'(* ses)<<「SELECT COUNT(*)FROM customer」'將起作用。 或者:Session&sessRef = * ses; sessRef <<「SELECT COUNT(*)FROM customer'如果你覺得它太笨拙 –

+0

謝謝,使用第一個版本 – Pheonix

0

看起來像registerConnector是一項免費功能。要調用初始化列表內的其他功能,您可以用逗號:

database() 
    : ses(
     (Poco::Data::ODBC::Connector::registerConnector(), "ODBC") 
     , "DSN=name;uid=user;pwd=pass" 
    ) 
{...} 

的內置逗號運算兩個表達式,並返回第二個結果。

或者,您可以創建一個處理registerConnector()類的自定義類,並將其放置在類ses之前的類中,以使其構造將在ses之前發生。

+0

編譯器說'registerConnector'在這種情況下是不確定的 – Pheonix

+0

@Pheonix:你應該 - 當然 - 在實際代碼中使用全名,所以它實際上應該是'Poco :: Data :: ODBC :: Connector :: registerConnector() –

+0

我也試過了,錯誤表示參數列表不匹配 – Pheonix

1

要直接實現這種功能,你寫周圍的registerConnector功能的RAII風格的包裝對象:

class wrapper { 
public: 
    wrapper() { 
     Poco::Data::ODBC::Connector::registerConnector(); 
    } 
    ~wrapper() { 
     Poco::Data::ODBC::Connector::unregisterConnector(); 
    } 
} 

所以,你現在可以做的:

class database{ 
    Wrapper wrap; 
    Session ses; //Since this is needed all for all the queries. 
    public: 
    database() : wrap(), ses("ODBC", "DSN=name;uid=user;pwd=pass"){ 
    } 
}; 

不過,我不我認爲這是一個很好的設計;它留下懸而未決的問題:

  1. 你爲什麼在database包裝初始化數據庫子系統?也許它應該作爲程序初始化例程的一部分來完成?
  2. 如果同時使用多個database對象,會發生什麼情況?註冊/取消註冊會導致問題;如上所述做init不會。
+0

我想你會想在之前聲明Wrapper會話,以便它首先被實例化/初始化。構造函數初始化列表不會控制這個(至少不會在gcc中會警告這個代碼)。 –

+1

'ses'會先被初始化。初始化列表中的評估順序是成員定義的順序,而不是它們在初始化列表中調用的順序。這是因爲需要確保所有構造函數中的單個順序,以便析構函數能夠以相反順序破壞事物。 –

+0

@Jon:好的,我做了這個,但是這似乎並不能解決問題,不知怎的,換行之前不會調用wrap(就像上面提到的Nathan可能)。 對於你的問題,我認爲它不是很好的設計,但我不是非常有經驗的+/-各種設計。我還是個學生。 1.我想它應該與程序init例程,我試圖保持數據庫部分分開。 2.由於我有一個單一的數據庫進行查詢,我計劃一次只保留一個對象,雖然我看到你指向多個數據庫。 謝謝 – Pheonix