我错误地写了下面的代码。 它适用于Windows(使用VS2010)但不适用于Mac(GCC)。
有人可以在此处描述返回类型上究竟发生了什么,以及为什么它在Mac Release版本中不起作用。
const Mystruct* const & GetMyObject() const
{
return m_pObject;
}
m_pObject是在堆上分配的此类中的指针。
编辑: 上面的代码在Mac上编译。但是当我执行以下语句时,它给了我一个垃圾指针
Mystruct* pObjectTemp = const_cast<Mystruct*>(GetMyObject());
答案 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)
另外,在gcc中运行的代码往往会在VS上运行,但反过来情况并非如此。