与返回类型混淆(引用,const引用)

时间:2013-08-15 12:40:12

标签: c++ reference

我错误地写了下面的代码。 它适用于Windows(使用VS2010)但不适用于Mac(GCC)。

有人可以在此处描述返回类型上究竟发生了什么,以及为什么它在Mac Release版本中不起作用。

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

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

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

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

4 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分: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提及here

答案 2 :(得分:1)

  

有人可以在这里描述返回类型上发生的事情吗

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

  

以及为何它无法在Mac Release版本上运行。

你忘了展示Mystruct的声明,但我猜它是一个声明为:

的成员
Mystruct* m_pObject;

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

在这种情况下,您尝试返回对错误指针类型的引用:const Mystruct*而不是Mystruct*。为了返回正确的类型,该函数必须创建一个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

答案 3 :(得分:0)

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

另外,在gcc中运行的代码往往会在VS上运行,但反过来情况并非如此。