ďťż

Ładny brzuch

Pisze sobie małego singletona do łączenia z baza. Oto kod:
//singleton.hpp namespace core { class DBase : private boost::noncopyable{ public: class DBError : public std::runtime_error{ public: DBError(const std::string& msg); ~DBError() throw(); }; static DBase* Instance(); enum DBName { MYSQL=0, POSTGRESQL}; bool connect(const std::string& connectString, DBName base/* = MYSQL*/); private: DBase(); ~DBase(); static bool initialized; static DBase instance; public: typedef SOCI::Session* _sql; public: static bool is_connect; // _sql sql; }; // typedef SOCI::Session* _sql; DBase::_sql sql; } //singleton.cpp using namespace core; DBase::DBError::DBError(const std::string& msg) : std::runtime_error(msg){ } DBase::DBError::~DBError() throw() { } bool DBase::initialized; bool DBase::is_connect; DBase DBase::instance; //Session* DBase::sql; DBase::DBase(){ initialized = true; is_connect = false; } DBase::~DBase(){ initialized = false; if(is_connect){ delete sql; } } DBase* DBase::Instance(){ return initialized ? &instance : 0; } bool DBase::connect(const std::string& connectString, DBName base/* = MYSQL*/){ switch(base){ case MYSQL: sql = new SOCI::Session(SOCI::mysql, connectString); break; case POSTGRESQL: // sql = new Session(postgresql, connectString); break; default: throw DBError("niezdefiniowana badz bledna nazwa bazy danych"); //return false; } is_connect=true; return true; } //main.cpp using namespace std; using namespace core; using namespace SOCI; int main(){ DBase *baza = DBase::Instance(); if(!baza->is_connect) cout << "nie polaczony" << endl; baza->connect("db=lszk user=root password='pas'",DBase::MYSQL); if(baza->is_connect) cout << "polaczony z baza" << endl; string text; int id; Row x; *sql << "select * from testowa where id=1", into(x); x >> id >> text; cout << id << ' ' << text << endl; }
Jak widac: nic specjalnego.
Jednak coś się pluje kompilator przy linkowaniu:

/tmp/ccohlwdw.o:(.bss+0x0): multiple definition of `core::sql'
/tmp/ccPeQ17j.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

Nie wiem, jak to ugryźć.

PS. Kompilator to gcc.



sprobuj tak:

w pliku hpp

daj zamiast DBase::_sql sql;
extern DBase::_sql sql;

a w pliku cpp dodaj
DBase::_sql sql;

Z extern nie działa
/tmp/cczDfL9F.o: In function `main':
undefined reference to `core::sql'
/tmp/ccFLpbDP.o: In function `~DBase':
undefined reference to `core::sql'
undefined reference to `core::sql'
/tmp/ccFLpbDP.o: In function `core::DBase::connect(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, core::DBase::DBName)':
undefined reference to `core::sql'
collect2: ld returned 1 exit status

Ale to nieistotne, bo poradziłem sobie inaczej. Mianowicie tego pointera wpakowałem do klasy oraz napisałem mu funkcje do zwracania. Troche to nie jest to, co chciałem osiągnąć (dodatkowa linijka w main), ale jakoś to strzymie :)
Jakby ktoś chciał zajrzeć:
//singleton.hpp namespace core { class DBase : private boost::noncopyable{ public: class DBError : public std::runtime_error{ public: DBError(const std::string& msg); ~DBError() throw(); }; static DBase* Instance(); enum DBName { MYSQL=0, POSTGRESQL}; bool connect(const std::string& connectString, DBName base = MYSQL); SOCI::Session* get() const; private: DBase(); ~DBase(); static bool initialized; static DBase instance; public: static bool is_connect; SOCI::Session* sql; }; } //singleton.cpp using namespace core; DBase::DBError::DBError(const std::string& msg) : std::runtime_error(msg){ } DBase::DBError::~DBError() throw() { } bool DBase::initialized; bool DBase::is_connect; DBase DBase::instance; DBase::DBase(){ initialized = true; is_connect = false; } DBase::~DBase(){ initialized = false; if(is_connect){ delete sql; } } DBase* DBase::Instance(){ return initialized ? &instance : 0; } bool DBase::connect(const std::string& connectString, DBName base){ switch(base){ case MYSQL: sql = new SOCI::Session(SOCI::mysql, connectString); break; case POSTGRESQL: //sql = new SOCI::Session(SOCI::postgresql, connectString); break; default: throw DBError("niezdefiniowana badz bledna nazwa bazy danych"); } is_connect=true; return true; } SOCI::Session* DBase::get() const{ return sql; } //main.cpp using namespace std; using namespace core; using namespace SOCI; int main(){ DBase *baza = DBase::Instance(); if(!baza->is_connect) cout << "nie polaczony" << endl; baza->connect("db=lszk user=root password='pas'",DBase::MYSQL); if(baza->is_connect) cout << "polaczony z baza" << endl; string text; int id; Row x; Session* xy=baza->get(); *xy << "select * from testowa where id=1", into(x); x >> id >> text; cout << id << ' ' << text << endl; }
Użytkownik lszk edytował ten post 26 wrzesień 2007, 16:55
jezeli chciałbys jednak wrócic do poprzedniego to sprobuj extern dac poza namespace {} w pliku hpp
pomysle nad jakims sposobem pozniej moze zeby nie trzeba bylo tego dawac poza

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • zsf.htw.pl
  •