c++ class member initialization (poco)
-
21-02-2021 - |
Question
i am making a wrapper for my use for database, using Poco::Database::ODBC
the normal code is supposed to be like :
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();
This works just fine.
Now for my class
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
how do i call Poco::Data::ODBC::Connector::registerConnector()
before initialization call of ses
I tried
database():Poco::Data::ODBC::Connector::registerConnector(),ses("ODBC", "DSN=name;uid=user;pwd=pass"){
}
but this doesnt works. it gives error
'registerConnector' : is not a member of 'Poco::Data::ODBC::Connector'
how should i do it ??
Solution
Either do it outside database::database()
, or use a pointer to a Session
instead of a member, and allocate it on the heap inside the constructor. Something like:
database::database()
{
Poco::Data::ODBC::Connector::registerConnector();
ses = new Session("ODBC", "DSN=name;uid=user;pwd=pass");
}
database::~database()
{
delete ses;
}
OTHER TIPS
To enable this kind of functionality directly, you write a RAII-style wrapper object around the registerConnector
function:
class wrapper {
public:
wrapper() {
Poco::Data::ODBC::Connector::registerConnector();
}
~wrapper() {
Poco::Data::ODBC::Connector::unregisterConnector();
}
}
So you can now do:
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"){
}
};
However, I don't think this is a good design; it leaves unanswered questions:
- Why are you initializing the database subsystem in the
database
wrapper? Maybe it should be done as part of the program's init routine? - What happens if multiple
database
objects get used at the same time? Registering/unregistering would cause problems; doing the init as above would not.
It looks like registerConnector
is a free function. To call other functions within the initialization list, you can use the comma operator:
database()
: ses(
( Poco::Data::ODBC::Connector::registerConnector(), "ODBC" )
, "DSN=name;uid=user;pwd=pass"
)
{...}
The builtin comma operator evaluates two expressions and returns the result of the second one.
Alternatively, you may be able to create a custom class that handles the registerConnector()
class, and place it within the class before ses
so that its construction will happen before that of ses
.