0

私はコードを持っています:

私のベクトル:std::vector<spreadsheet> spreadsheets;

//create a new spreadsheet if it doesn't already exist. Link the session to the spreadsheet.
bool server::createSpreadsheet(session* session, std::string name, std::string password)
{
    std::cout << "beginning" << std::endl;

    bool found = false;
    for(int i = 0; i < spreadsheets.size(); i++)
    {

      spreadsheet test = spreadsheets.at(i);
      std::cout << "spreadsheet name = " << &test << std::endl;
      if(spreadsheets.at(i).name == name) //spread sheet already exists
      {
          found = true;

      }
    }
    std::cout << "After For found = " << found << std::endl;

    if(!found) //create a spreadsheet
    {
      spreadsheet * spr = new spreadsheet(name, password);
      spr->linkSession(session);
      spreadsheets.push_back(*spr);
    }
    else
    {
      std::cout << "in else" << std::endl;
      return false;
    }
    return true;
}

これにより、毎回新しいスプレッドシート オブジェクトが作成され、ベクターに配置されることを期待しfoundfalseいました。しかし、私が得ている出力に基づいて、毎回同じオブジェクトを置いているようですか? ここで何が起こっているのか途方に暮れていますか?

数回実行した後の出力:

beginning
spreadsheet name = 0x7fff568bce10
spreadsheet name = 0x7fff568bce10
spreadsheet name = 0x7fff568bce10
spreadsheet name = 0x7fff568bce10
spreadsheet name = 0x7fff568bce10
spreadsheet name = 0x7fff568bce10
spreadsheet name = 0x7fff568bce10
spreadsheet name = 0x7fff568bce10
spreadsheet name = 0x7fff568bce10
4

3 に答える 3

5

スプレッドシートをローカル変数にコピーします。そして、ローカル変数のアドレスを出力します。

ベクター自体にスプレッドシートのアドレスを出力したい場合は、次のようにします。

std::cout << "スプレッドシート名 = " << &spreadsheets[i] << std::endl;

于 2013-04-21T05:27:56.593 に答える
1
spreadsheet test = spreadsheets.at(i);

コピーの初期化です。つまり、新しいスプレッドシート オブジェクトtestが作成され、そこにあるものが値spreadsheets.at(i)によってコピーされます

test次に、新しいオブジェクトのアドレスを常に取得しています。ベクトル内の値のアドレスではありません。

のスコープはtestfor ループ内にあります。そのため、コンパイラは反復ごとに同じアドレスに割り当て続け、同じアドレスを表示します。

入っているもののアドレスが必要な場合はat(i)spreadsheetsそのアドレスを直接取得する必要があります

std::cout << "spreadsheet name = " << &spreadsheets.at(i) << std::endl;
于 2013-04-21T05:27:45.997 に答える
1

毎回同じオブジェクトを入れているようですか?

いいえ。一時的なローカル変数 ( test) がメモリ内の特定の場所に配置されているだけです。もちろん、そのアドレスは変更されません。それらを区別できるようにするには、オブジェクトの内容を検査する必要があります。

また、あなたが使用している方法vectornew、少なくともひどく間違っています。適切に割り当てられたスプレッドシート オブジェクトのコピーをプッシュバックし、余分にコピー コンストラクターを呼び出すと、元のオブジェクトへのポインターが失われ、メモリ リークが発生します。newベクターからオブジェクトを取得すると、再度コピーされます。なんで参考にしないの?

spreadsheet spr(name, password);
spr.linkSession(session);
spreadsheets.push_back(spr); // this copies too, but at least only once

// ...

/* optionally: const */ spreadsheet &test = spreadsheets.at(i);

また、反復子を使用してベクトルを反復処理することをお勧めします。

for (vector<spreadsheet>::iterator it = spreadsheets.begin(); it != spreadsheets.end(); it++) {
    // use `*it` to access the current element
}
于 2013-04-21T05:32:26.523 に答える