7

関数をQtConcurrent::run実行して値を参照渡ししていましたが、値のメモリアドレスが異なります。

しかし、ポインタで値を渡すと、アドレスは同じです! 私はそれを理解することはできません。私は何かが恋しいですか?

これがコードです。

void ptr(QString* s)
{
    qDebug() << "pass by ptr: " << s;
}

void ref(QString& s)
{
    qDebug() << "pass by ref: " << &s;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QString str;
    QFuture<void> f1 = QtConcurrent::run(ptr, &str);
    f1.waitForFinished();

    QFuture<void> f2 = QtConcurrent::run(ref, str);
    f2.waitForFinished();

    qDebug() << "address of str: " << &str;

    return a.exec();
}

出力:

pass by ptr:  0x28fefc
pass by ref:  0x525de4
address of str:  0x28fefc
4

2 に答える 2

13

QtConcurrent::run渡されたすべての引数の内部コピーを作成します。その後、スレッド関数には、元の引数ではなく、これらのコピーへのアクセスが与えられます。生の参照で何かを渡しても、コピーの作成は妨げられません。つまり、QtConcurrent::run値渡しのセマンティクスを内部的に強制します。

関数に表示されるrefアドレスは、その内部コピーのアドレスです。

このため、元のオブジェクトへのアクセスが特に必要な場合は、ネイキッド参照の代わりに、ポインター セマンティクスまたは「コピー可能な参照」セマンティクスを備えたものを使用する必要があります。

于 2014-08-02T03:59:47.813 に答える
7

参照を使用する必要がある場合は、std::ref を使用します。新しいコードは次のようになります。

#include <functional>
...

QFuture<void> f2 = QtConcurrent::run(ref, std::ref(str));
于 2014-08-02T08:34:06.697 に答える