|
-
November 5th, 2016, 05:21 AM
#1
Class templates inheritance
Hi. I'm new. I try to create abstract database class Db and derived class Pg to handle at least connection to the database. I have private property with database connection type and because it will be unique depending on database I should implement templates.
Code:
#include <iostream>
#include <postgresql/libpq-fe.h>
using namespace std;
template <class T>
class Db
{
public:
Db(string, string, string, string);
Db();
string getHost();
string getUsername();
string getDatabase();
string getPassword();
virtual string getConnectionString()=0;
virtual ~Db();
protected:
T* m_conn;
string m_host;
string m_username;
string m_database;
string m_password;
};
template <class T>
class Pg : public Db<T> {
public:
Pg(string, string, string, string);
Pg();
virtual ~Pg();
virtual string getConnectionString();
};
template <class T>
string Db<T>::getHost() {
return m_host;
}
// ---------------------------------------------------------------------
// username, database and password getters are implementing the same way
// ---------------------------------------------------------------------
template <class T>
Pg<T>::Pg(string host, string username, string database, string password)
// I intentionally remove Pg:: for m_host property
: m_host(host), Pg::m_username(username), Pg::m_database(database), Pg::m_password(password) {
Pg::m_conn = PQconnectdb(getConnectionString().c_str());
if (PQstatus(Pg::m_conn) == CONNECTION_BAD) {
puts("Unable to connect to database");
exit(0);
}
}
template <class T>
string Pg<T>::getConnectionString() {
return "host=" + this->getHost() + " user=" + this->getUsername()
+ " password=" + this->getPassword() + " dbname=" + this->getDatabase();
}
int main () {
Pg<PGconn> conn("localhost", "pg", "pg", "pwd");
return 0;
}
When I compile this beautiful code I get an errors:
Code:
load.cpp: In constructor ‘Pg<T>::Pg(std::string, std::string, std::string, std::string)’:
load.cpp:50:7: error: class ‘Pg<T>’ does not have any field named ‘m_host’
: m_host(host), Pg::m_username(username), Pg::m_database(database), Pg::m_password(password) {
^
load.cpp: In instantiation of ‘Pg<T>::Pg(std::string, std::string, std::string, std::string) [with T = pg_conn; std::string = std::basic_string<char>]’:
load.cpp:73:52: required from here
load.cpp:50:96: error: no type named ‘m_username’ in ‘class Pg<pg_conn>’
: m_host(host), Pg::m_username(username), Pg::m_database(database), Pg::m_password(password) {
^
load.cpp:50:96: error: no type named ‘m_database’ in ‘class Pg<pg_conn>’
load.cpp:50:96: error: no type named ‘m_password’ in ‘class Pg<pg_conn>’
As you can see if I remove Pg:: before m_host property I get the error that class does not have such field. If I place Pg:: before another connection properties I get the error no type named ‘m_database’.
I completely stuck for two days with this issue.
I use linux and g++ compiler:
g++ -o load -g load.cpp -std=c++11 -lcurl -lpq
-
November 5th, 2016, 06:01 AM
#2
Re: Class templates inheritance
To initialise members of the base class, call a base class constructor eg
Code:
template <class T>
Pg<T>::Pg(string host, string username, string database, string password)
// I intentionally remove Pg:: for m_host property
//: m_host(host), Pg::m_username(username), Pg::m_database(database), Pg::m_password(password) {
: Db<T>(host, username, database, password) {
...
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
November 5th, 2016, 06:17 AM
#3
Re: Class templates inheritance
Thanks a lot, 2kaud! These errors disappear, but now I have another. Seems I don't understand the way inheritance work in C++:
Code:
/tmp/cc8AwHUL.o: In function `Pg<pg_conn>::Pg(std::string, std::string, std::string, std::string)':
/home/arra/Projects/mudobot/rates/load.cpp:62: undefined reference to `Db<pg_conn>::Db(std::string, std::string, std::string, std::string)'
collect2: error: ld returned 1 exit status
-
November 5th, 2016, 07:13 AM
#4
Re: Class templates inheritance
Based upon the code in post #1, the below compiles and executes. For test I've just set type PGconn to int
Code:
#include <string>
#include <iostream>
using namespace std;
typedef int PGconn;
template <class T>
class Db
{
public:
Db(string h, string u, string d, string p) : m_host(h), m_username(u), m_database(d), m_password(p) {}
Db() {}
string getHost() const { return m_host; }
string getUsername() const { return m_username; }
string getDatabase() const { return m_database; }
string getPassword() const { return m_password; }
virtual string getConnectionString() const = 0;
virtual ~Db() {}
protected:
T* m_conn = nullptr;
string m_host;
string m_username;
string m_database;
string m_password;
};
template <class T>
class Pg : public Db<T> {
public:
Pg(string, string, string, string);
Pg() {}
virtual ~Pg() {}
virtual string getConnectionString() const;
};
template <class T>
Pg<T>::Pg(string host, string username, string database, string password)
: Db<T>(host, username, database, password) {
/*
if (PQstatus(Pg::m_conn) == CONNECTION_BAD) {
puts("Unable to connect to database");
exit(0);
}
*/
}
template <class T>
string Pg<T>::getConnectionString() const {
return "host=" + getHost() + " user=" + getUsername()
+ " password=" + getPassword() + " dbname=" + getDatabase();
}
int main() {
Pg<PGconn> conn("localhost", "pg", "pg", "pwd");
cout << conn.getConnectionString() << endl;
return 0;
}
if your code is now different, it would be useful if you could post your revised code.
Last edited by 2kaud; November 5th, 2016 at 07:20 AM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
November 5th, 2016, 08:05 AM
#5
Re: Class templates inheritance
Great thanks!! I made it work with help of your better version of my code =)
But one thing I don't understand is why should I add this-> anyway, because your version without this-> crashed with:
Code:
rates/load.cpp: In member function ‘virtual std::string Pg<T>::getConnectionString() const’:
rates/load.cpp:55:63: error: there are no arguments to ‘getUsername’ that depend on a template parameter, so a declaration of ‘getUsername’ must be available [-fpermissive]
return "host=" + this->getHost() + " user=" + getUsername()
May be I forgot something from your version, thanks anyway. Here is the end working version:
Code:
#include <iostream>
#include <vector>
#include <string>
#include <postgresql/libpq-fe.h>
using namespace std;
template <class T>
class Db
{
public:
Db(string h, string u, string d, string p)
: m_host(h), m_username(u), m_database(d), m_password(p) {}
Db() {}
virtual ~Db() {}
string getHost() const { return m_host; }
string getUsername() const { return m_username; }
string getDatabase() const { return m_database; }
string getPassword() const { return m_password; }
virtual string getConnectionString() const = 0;
protected:
T* m_conn;
string m_host;
string m_username;
string m_database;
string m_password;
};
template <class T>
class Pg : public Db<T> {
public:
Pg(string, string, string, string);
Pg() {}
virtual ~Pg() {}
virtual string getConnectionString() const;
};
template <class T>
Pg<T>::Pg(string host, string username, string database, string password)
: Db<T>(host, username, database, password) {
Pg::m_conn = PQconnectdb(getConnectionString().c_str());
if (PQstatus(Pg::m_conn) == CONNECTION_BAD) {
puts("Unable to connect to database");
exit(0);
}
}
template <class T>
string Pg<T>::getConnectionString() const {
return "host=" + this->getHost() + " user=" + this->getUsername()
+ " password=" + this->getPassword() + " dbname=" + this->getDatabase();
}
int main () {
Pg<PGconn> conn("a", "b", "c", "d");
cout << conn.getConnectionString() << endl;
return 0;
}
-
November 5th, 2016, 08:49 AM
#6
Re: Class templates inheritance
Without the this-> in getConnectionString(), it works OK with MS VS2015. Sorry. I don't use the g++ compiler so can't comment on its error. Perhaps a guru who does use g++ can elaborate?
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
November 5th, 2016, 09:00 AM
#7
Re: Class templates inheritance
Strange thing. When I separate that code on files Db.h Pg.h and Pg.cpp I again get the error:
Code:
/tmp/ccCNyID2.o: In function `main':
rates/load.cpp:71: undefined reference to `Pg<pg_conn>::getConnectionString() const'
/tmp/ccCNyID2.o: In function `Pg<pg_conn>::Pg(std::string, std::string, std::string, std::string)':
rates/../src/db/Pg.h:12: undefined reference to `Pg<pg_conn>::getConnectionString() const'
/tmp/ccCNyID2.o:(.rodata._ZTV2PgI7pg_connE[_ZTV2PgI7pg_connE]+0x20): undefined reference to `Pg<pg_conn>::getConnectionString() const'
collect2: error: ld returned 1 exit status
It's really copy-paste, the difference only in head of the files where I do includes:
Code:
Pg.h: #include "Db.h"
Pg.cpp: #include "Pg.h"
main.cpp: #include "../src/db/Pg.h"
-
November 5th, 2016, 12:19 PM
#8
Re: Class templates inheritance
I suspect this is because you are splitting the class definition from its implementation (Pg.g and Pg.cpp). When templates are involved, the implementation is usually in the same unit as its definition (often a .hpp file).
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
November 6th, 2016, 08:29 AM
#9
Re: Class templates inheritance
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|