1

我错误地结束了编写以下代码。它适用于 Windows(使用 VS2010),但不适用于 Mac(GCC)。

有人可以描述这里的返回类型到底发生了什么,以及为什么它在 Mac Release 版本上不起作用。

const Mystruct* const & GetMyObject() const
{
    return m_pObject;
}

m_pObject 是该类中在堆上分配的指针。

编辑:上面的代码在 Mac 上编译。但是当我执行以下语句时,它给了我一个垃圾指针

Mystruct* pObjectTemp = const_cast<Mystruct*>(GetMyObject());
4

4 回答 4

7

它是对指向常量 Mystruct 的指针的常量引用。

于 2013-08-15T12:42:12.983 回答
1

有人可以在这里描述返回类型上到底发生了什么吗

返回类型是对指向常量Mystruct对象的常量指针的引用。

以及为什么它不适用于 Mac Release 版本。

您忘记显示 的声明Mystruct,但我猜它是声明为的成员:

Mystruct* m_pObject;

请注意,没有const,使其成为const Mystruct*函数返回引用的不同指针类型。

在这种情况下,您试图返回对错误指针类型的引用:const Mystruct*而不是Mystruct*. 为了返回正确的类型,函数必须创建一个 type 的临时指针const Mystruct*。但是,在返回对临时对象的引用后,它会超出范围并可能被垃圾覆盖:使用返回值会产生未定义的行为。

要修复它,请按值返回指针:

const Mystruct* GetMyObject() const {return m_pObject;}

您可能还需要一个非常量的重载,以避免需要狡猾的铸造:

Mystruct* GetMyObject() {return m_pObject;}

更新:

为了证明这确实是问题所在(假设我猜测 的类型是正确的m_pObject),请考虑以下内容:

#include <iostream>

struct Mystruct {};

struct Test {
    Test() : m_pObject(0) {}

    const Mystruct * const & GetMyObject() const {
        return m_pObject;
    }

    Mystruct * m_pObject;
};

int main() {
    Test test;

    std::cout << "MEMBER: " << &test.m_pObject << std::endl;
    std::cout << "RETURN: " << &test.GetMyObject() << std::endl;
}

编译器识别问题:

$ g++ test.cpp
test.cpp: In member function ‘const Mystruct* const& Test::GetMyObject() const’:
test.cpp:9:16: warning: returning reference to temporary [enabled by default]

并运行它表明返回的引用不引用该成员:

$ ./a.out 
MEMBER: 0x7fff7a3c4c20
RETURN: 0x7fff7a3c4c08
于 2013-08-15T13:56:44.200 回答
1

您正在返回对常量指针的常量引用,然后使用const_cast将其转换为原始指针。该转换不起作用: http ://en.cppreference.com/w/cpp/language/const_cast

const Mystruct* pObjectTemp = t.GetMyObject();

这应该返回您在实例化t对象中的相同指针(请注意,如果 t 在堆栈上,一旦超出范围,析构函数应该清理它的内存,这意味着 pObjectTemp 将指向不再分配的内存)。

您还应该修改您的功能:

const Mystruct* const GetMyObject() const
{
    return m_pObject;
}

在这种情况下,通过引用返回指针并没有真正的好处,并且更改它可以防止 Mike在这里提到的问题。

于 2013-08-15T13:53:38.627 回答
0

VS 决定放宽对 const 的解释,并允许返回一个变量指针。在类型检查方面更严格的 Gcc 没有。

顺便说一句,在 gcc 中运行的代码往往会在 VS 上运行,但反之则不一定。

于 2013-08-15T13:00:51.830 回答