C++类成员初始化(POCO)
我想提出一个包装为我用的数据库,采用波科::数据库:: 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'
我应该怎么办呢?
要么在database::database()
以外,要么使用指向Session
而不是成员的指针,并将其分配到构造函数中的堆上。例如:
database::database()
{
Poco::Data::ODBC::Connector::registerConnector();
ses = new Session("ODBC", "DSN=name;uid=user;pwd=pass");
}
database::~database()
{
delete ses;
}
看起来像registerConnector
是一项免费功能。要调用初始化列表内的其他功能,您可以用逗号:
database()
: ses(
(Poco::Data::ODBC::Connector::registerConnector(), "ODBC")
, "DSN=name;uid=user;pwd=pass"
)
{...}
的内置逗号运算两个表达式,并返回第二个结果。
或者,您可以创建一个处理registerConnector()
类的自定义类,并将其放置在类ses
之前的类中,以使其构造将在ses
之前发生。
要直接实现这种功能,你写周围的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"){
}
};
不过,我不我认为这是一个很好的设计;它留下悬而未决的问题:
- 你为什么在
database
包装初始化数据库子系统?也许它应该作为程序初始化例程的一部分来完成? - 如果同时使用多个
database
对象,会发生什么情况?注册/取消注册会导致问题;如上所述做init不会。
我想你会想在之前声明Wrapper会话,以便它首先被实例化/初始化。构造函数初始化列表不会控制这个(至少不会在gcc中会警告这个代码)。 –
'ses'会先被初始化。初始化列表中的评估顺序是成员定义的顺序,而不是它们在初始化列表中调用的顺序。这是因为需要确保所有构造函数中的单个顺序,以便析构函数能够以相反顺序破坏事物。 –
@Jon:好的,我做了这个,但是这似乎并不能解决问题,不知怎的,换行之前不会调用wrap(就像上面提到的Nathan可能)。 对于你的问题,我认为它不是很好的设计,但我不是非常有经验的+/-各种设计。我还是个学生。 1.我想它应该与程序init例程,我试图保持数据库部分分开。 2.由于我有一个单一的数据库进行查询,我计划一次只保留一个对象,虽然我看到你指向多个数据库。 谢谢 – Pheonix
'ses'用于像'ses Pheonix
'(* ses)
谢谢,使用第一个版本 – Pheonix