0

スマートフォン用のC++アプリを構築するためのプラットフォームであるAirplaySDKを使用しています。また、MS Visual C ++IDE+コンパイラを使用するx86シミュレータもあります。

今、私はこのクラスを持っています:

namespace Fair {

    class Bitmap : public Sprite {

    public:

        const CIw2DImage* const& getBitmapData() { return bitmapData; }; // warning: returning reference to temporary

    private:

        CIw2DImage* bitmapData;
    };

}

GCC(ARM)デバッグでビルドすると、上記の警告が表示されます。(x86)デバッグで警告が表示されません。

私は他の場所で尋ねました、そして私はこの返事を得ました:

`const CIw2DImage * const'はconstCIw2DImageへのconstポインターであり、Bitmap::bitmapDataは非constへのポインターであるためCIw2DImageコンパイラーは自動的にnon-constへのポインターをconstにキャストします。次のコードは、「一般的な」コンパイラによって生成される可能性があります。

const CIw2DImage* const& getBitmapData() {
    const CIw2DImage* const tmp = bitmapData;
    return tmp;
}

おそらく(x86)コンパイラはこの問題を検出しません。

プロトタイプから参照記号(&)を削除することをお勧めします(この場合、なぜ参照を使用するのですか?)

コンパイラがそれを行う場合、それは完全に間違った慣行です..?返される値をより「厳密」にすることは、「乱用」を防ぐために、単にコンパイラレベルで行われます。(x86)最初のケースでは問題を「引き起こさない」ため、検出されません。

32ビットのメモリを「節約」するという唯一の理由でポインタへの参照を返します。つまり、bitmapDataポインタと同じメモリブロックを使用しますが、コンテキストは異なります。

コメントをお願いします。

4

2 に答える 2

2

コンパイラはそれを行うのに非常に正しいです。参照は、正しいタイプのオブジェクトを参照する必要があります。ここにタイプのオブジェクトがCIw2DImage*あり、別のタイプへの参照が必要ですconst CIw2DImage*。これを行う唯一の方法は、正しいタイプの一時的なものを作成し(const T*暗黙的にに変換できるため、ここで可能ですT*)、その参照を返すことです。

残念ながら、その結果、関数のスコープ内の一時オブジェクトへの参照が発生します。これは、関数が戻ると無効になります。

最も簡単な解決策は、ポインタを値で返すことです。これは、この問題を回避するだけでなく、より効率的になります(不必要なレベルの間接参照を回避するため)。

于 2011-02-12T12:52:35.923 に答える
0

参照を返すメモリはまったく保存されません。これは内部の単なるポインタです。さらに、constはコンパイル時に完全に発生するため、一時的なものが生成される理由はありません。生成されたとしても、constへの参照は有効です。

そのコードは個人的にはひどいように見えますが、決して未定義ではありません。

于 2011-02-12T12:34:07.407 に答える