0

MySQL データベースにクエリを実行するアプリケーションを作成しています。

この結果をマップ (対応するペアを持つ) に保存したい:

std::map<int, Car*> m_car;
typedef std::pair<int, Car*> m_car_pair;

車のオブジェクトは 8 つのパラメーターで構成されており、そのうちの 1 つが car_id であるため、まず車の ID を取得してキーとして使用し、次に車のオブジェクト全体をマップの値として保存します。(私はこれが car_id を 2 回保存するように仕向けていることを知っていますが、今のところ気にしません)。

とにかく、ここに私のクエリコードがあります:

void DatabaseController::getAll(QString query_string)
{
    // Console log message
    std::cout << "Querying Database" << std::endl;

    /// Declare SQL query and pass function parameter 'query'
    QSqlQuery query(query_string);

    // execute the query
    query.exec();

    int count = 0;

    // While results are coming in
    while(query.next())
    {
        // Call car constructor passing all parameters
        Car car(query.value(count).toInt(), query.value(count+1).toString(), query.value(count+2).toString(), query.value(count+3).toString(),
            query.value(count+4).toInt(), query.value(count+5).toInt(), query.value(count+6).toInt(), query.value(count+7).toString());

        if (car.getcarID() != 0)
        {
            m_car_records.insert(m_car_pair(car.getcarID(), &car));
        }
    }

    std::cout << "Database query finished" << std::endl;

この後、マップを反復処理してすべての ID (マップ キー) を取得し、それらが異なる (つまり、関数が機能した) かどうかを確認する簡単なテスト関数を作成しました。

しかし、それは私が必要としていたのは、マップにあるはずの車のオブジェクトで車からアクセサリ関数を呼び出せるようにすることだけでした。そこで、同じクイック テスト関数を使用してマップを反復処理し、cout << car.toString();(car クラスの単純な文字列関数):

void DatabaseController::test()
{
    m_car_records_iterator = m_car_records.begin();

    for(unsigned int i = 0; i < m_car_records.size(); i++)
    {
        car *test = m_car_records_iterator->second;
        std::cout << test->toString() << std::endl;
        m_car_records_iterator++;
    }
}

これは正しい数の結果を示しましたが、それらはすべて同じでした。つまり、マップ内のすべてのエントリに追加された車のオブジェクトは同じです (クエリによって見つかった最後のレコードの値)。

私の質問は...

現在クエリに使用しているこの構造を使用して、while ループ内でこれらのクラス オブジェクトを作成し、それぞれに同じ名前を使用してマップに追加する方法はありますか?もちろん、返される結果の数を知ることはできません。それぞれに対してクラスオブジェクトを宣言しますが、同じ名前を使用すると、実際に値を置き換えるのではなく、毎回同じものを追加するだけです...少なくともそれが起こっていると思いますか??

アドバイスやアイデアは大歓迎です(長い投稿で申し訳ありません)

4

2 に答える 2

2

これはあなたの問題です--

Car car( ... );  // ***Stack allocated

if (car.getcarID() != 0)
{
    m_car_records.insert(m_car_pair(car.getcarID(), &car));
}
    //But the pointer is what's stored

ループが繰り返されると、Carインスタンスが破棄され、ポインターがぶら下がり、未定義の動作が発生します。あなたが必要

Car* car = new Car( ... );

m_car不要になったら、 とdeleteそのCar値を繰り返し処理する必要があります。

于 2013-04-12T15:19:11.333 に答える
2

未定義の動作が発生しています。その理由は、マップ内のローカル変数へのポインターを挿入するためです。

のループではgetAll、ループが次の項目で最初からやり直すと、car変数は無効になります。

std::shared_ptrポインタを調べることをお勧めします。

于 2013-04-12T15:18:38.197 に答える