0

我使用 Airplay SDK,它是一个为智能手机构建 C++ 应用程序的平台。它还有一个使用 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) Debug 构建,我会收到上述警告。我没有收到 (x86) Debug 的警告。

我在别处问过,我得到了这个答复:

因为 `const CIw2DImage* const' 是一个指向 const CIw2DImage 的 const 指针,而 Bitmap::bitmapData 是一个指向非 const CIw2DImage 的指针,编译器自动将指向非 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 回答