0

プログラムの終了時にデストラクタが呼び出されません。オブジェクトはシングルトンです。おそらく何か不足していますか?

ヘッダーと cpp ファイルは次のとおりです。

#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 */

そしてcppファイル

#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;
    }
}
4

2 に答える 2

7

deleteで作成されたオブジェクトを誰も呼び出していないため、デストラクタは呼び出されませんnew:

mysqlConnector = new MysqlConnector(); // Where's the corresponding call to delete?

代わりにスマート ポインターの使用を検討することもstd::unique_ptrできます (C++11 を購入できる場合は、 をお勧めします)。deleteこれは、スマート ポインター自体が破棄されたときに、カプセル化されたオブジェクトに対して自動的に呼び出されます。

もう 1 つの可能性は、ポインターをまったく使用せず、 type の静的データ メンバーを持つことMysqlConnectorです。getInstance()その後、そのオブジェクトへの (ポインターではなく) 参照を返すことができます。

于 2013-05-23T15:23:19.967 に答える
0
static MysqlConnector* mysqlConnector;

クラスへのポインタです。インスタンスを取得すると、このポインタが返されます。deleteデストラクタを呼び出すには、この静的ポインタを呼び出す必要があります。

先に進んでこのポインターで delete を呼び出す場合は、プログラムが終了したときにのみ呼び出すようにしてください。次の呼び出しgetInstance()で新しいオブジェクトが作成されるためです。

編集 - instanceFlag を見つけたので、新しいインスタンスは作成されませんが、NULL ポインターが返されます

シングルトンが同じオブジェクトであると期待するかもしれないので、これは問題ですが、もちろん、その新しいインスタンスを作成すると、(シングルトンにアクセスしていても) データは永続的ではなくなります。

OSは関係なくメモリを再利用するため、接続を閉じるコードを公開して自分で呼び出す方がよいでしょうか?

于 2013-05-23T15:25:25.087 に答える