Reputation: 10752
My destructor is not being called when the program exits. The object is a singleton, perhaps I am missing something?
Here is the header and cpp file:
#ifndef MYSQLCONNECTOR_H
#define MYSQLCONNECTOR_H
/* Standard C++ headers */
#include <iostream>
#include <string>
/* MySQL Connector/C++ specific headers */
#include <driver.h>
#include <connection.h>
#include <statement.h>
#include <prepared_statement.h>
#include <resultset.h>
#include <metadata.h>
#include <resultset_metadata.h>
#include <exception.h>
#include <warning.h>
class MysqlConnector {
private:
static bool instanceFlag;
static MysqlConnector* mysqlConnector;
MysqlConnector() {
};
public:
static sql::Driver *driver;
static sql::Connection *conn;
static MysqlConnector* getInstance();
virtual ~MysqlConnector() {
instanceFlag = false;
conn->close();
delete conn;
std::cout << "called" << std::endl;
};
private:
};
#endif /* MYSQLCONNECTOR_H */
And the cpp file
#include "MysqlConnector.h"
using namespace std;
using namespace sql;
bool MysqlConnector::instanceFlag = false;
MysqlConnector* MysqlConnector::mysqlConnector = NULL;
MysqlConnector* MysqlConnector::getInstance() {
if (!instanceFlag) {
mysqlConnector = new MysqlConnector();
instanceFlag = true;
try {
driver = get_driver_instance();
/* create a database connection using the Driver */
conn = driver->connect("tcp://127.0.0.1:3306", "root", "root");
/* turn off the autocommit */
conn -> setAutoCommit(0);
/* select appropriate database schema */
conn -> setSchema("exchange");
} catch (SQLException &e) {
cout << "ERROR: SQLException in " << __FILE__;
cout << " (" << __func__ << ") on line " << __LINE__ << endl;
cout << "ERROR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << ")" << endl;
if (e.getErrorCode() == 1047) {
cout << "\nYour server does not seem to support Prepared Statements at all. ";
cout << "Perhaps MYSQL < 4.1?" << endl;
}
} catch (std::runtime_error &e) {
cout << "ERROR: runtime_error in " << __FILE__;
cout << " (" << __func__ << ") on line " << __LINE__ << endl;
cout << "ERROR: " << e.what() << endl;
}
return mysqlConnector;
} else {
return mysqlConnector;
}
}
Upvotes: 0
Views: 1375
Reputation: 7176
static MysqlConnector* mysqlConnector;
Is the pointer to the class. When you get the instance it just returns this pointer. You need to call delete
on this static pointer for the destructor to be called.
If you do go ahead and call delete on this pointer, make sure you only do so when the program terminates though - since the next call to getInstance()
will create a new object.
EDIT - just spotted the instanceFlag so it won't create a new instance but would return a NULL pointer
This is problematic since you might expect the Singleton to be the same object, but of course creating a new instance of it will mean that your data will not be persistent (even though you are accessing a singleton).
The OS will reclaim the memory regardless, so you might be better to expose the connection closing code and calling that by yourself?
Upvotes: 0
Reputation: 126542
Your destructor is not getting called because nobody is calling delete
for an object created with new
:
mysqlConnector = new MysqlConnector(); // Where's the corresponding call to delete?
You may consider using a smart pointer instead (I would suggest std::unique_ptr
, if you can afford C++11). That would automatically called delete
on the encapsulated object when the smart pointer itself is destroyed.
Another possibility is to not use pointers at all, and have a static data member of type MysqlConnector
. getInstance()
could then return a reference (rather than a pointer) to that object.
Upvotes: 7