1

戻り値の最適化に関する多くの記事を読みました。ただし、これが次の場合に発生するかどうかを完全に理解することはできません (アドレスは実際には常に同じです)。

#include "stdafx.h"

class Type
{
public:
    Type(int a) { m_a = a; }
private:
    Type(const Type & other) {}
    int m_a;
};

class Base
{
public:
    Base() : instance(42) {}
    virtual Type & GetType()
    {
        printf("Base: Address of instance: %i\n", &instance);
        return instance;
    }

private:
    Type instance;
};

class Derived : public Base
{
public:
    virtual Type & GetType()
    {
        printf("Derived\n");
        return Base::GetType();
    }
};

int main()
{
    printf("Base class\n");
    Base b;
    printf("Main: Address of instance: %i\n", &(b.GetType()));

    printf("\nDerived class\n");
    Derived d;
    printf("Main: Address of instance: %i\n", &(d.GetType()));
}

参照によって戻ると、常にコピー コンストラクターが呼び出されないことが保証されますか?
それともここでRVOが行われていますか?

4

2 に答える 2

4

参照によって戻ると、常にコピー コンストラクターが呼び出されないことが保証されますか?

RVO は最適化手法です。規格では保証されていません。ほとんどのコンパイラは、値で戻るときに RVO を適用します。

virtual Type & GetType()
        ^^^^^^

ここでは参照によって返されます。つまり、コピーを作成する必要がないため、コピー コンストラクター呼び出しのオーバーヘッドがなく、RVO の可能性や範囲がありません。

アドレスは実際には常に同じです

これらのアドレスは、同じクラス メンバーのアドレスであるため、実際には常に同一です。

于 2013-02-18T11:13:58.150 に答える
3

参照によって戻ると、常にコピー コンストラクターが呼び出されないことが保証されますか?

はい。(値による受け渡しとは対照的に) 参照渡しまたは参照渡しの場合、コピーは作成されません。

RVOはここで開催されますか?

参照で戻るので、RVO はここでは関係ありません。RVO は、値によって返されるときに作成される冗長なコピーを排除する最適化手法です。

次のような関数がある場合、RVO が発生する可能性があります。

Type GetType()
{
    Type instance;
    //...
    return instance;
}
//...
Type t = GetType();

次に、RVO を使用すると、コンパイラは冗長なコピー コンストラクタデストラクタの呼び出しを排除しようとします。これは、コピーが作成されずにinstance、関数のローカルGetTypeが変数に割り当てられることを意味します。t

于 2013-02-18T11:09:51.240 に答える