我最近一直在学习 C++,今天才被介绍到 const 和 const 正确性的概念。为了更好地理解这个理论,我一直在编写一系列简单的程序来确保我正确理解了这个概念。我以为我什么都明白了,但是当在其中一个程序中使用 auto 关键字时,我似乎有点卡住了。
为了测试我是否理解 const 指针的工作原理,我编写了一个简单的程序。我不会费心发布整个事情,因为它只有两个部分是相关的。我有一个具有 int 类型的 const 数据成员的类:
const int tryToChangeMe;
在这个类中,我还有一个成员函数,它返回一个指向上述 const int 的 const 指针:
const int* const MyClass::test()
{
return &tryToChangeMe;
}
然后在我的主函数中调用上述函数,使用 auto 关键字。为了测试我认为我对 const 的了解是否正确,然后我尝试通过指针重新分配 tryToChangeMe 变量。像这样:
auto temp = myClass.test();
*temp = 100;
正如我所料,由于我在尝试为 const 变量赋值时导致的错误,程序无法编译。然而,我不只是返回一个指向 const 的指针,我返回了一个指向 const 的 const 指针(至少我是这么认为的)做过)。因此,为了测试这一点,我尝试将指针重新分配给一个新的内存地址,并确信我会得到类似的编译错误:
temp = new int;
但相当令人困惑的是,程序编译时没有任何问题。调试器逐步显示,果然,指针丢失了它的原始地址并被分配了一个全新的地址。想知道发生了什么,我碰巧删除了 auto 关键字并将其替换为变量的完整类型:
const int* const temp = myClass.test();
再次测试所有内容后,结果与预期一致,这次我无法将指针重新分配给新地址。
毕竟我想我的问题是,为什么?为什么 auto 关键字允许您绕过指针的 const 限定符?我是不是做错了什么?
顺便说一句,我不确定这是否重要,但我正在使用 Visual Studio 2015 预览版
最佳答案
如前所述,auto
忽略顶级 cv 限定符。阅读 this article了解 auto
和 decltype
如何工作的详细信息。
现在,即使 auto
没有忽略 const
,在您的情况下,temp
仍然不是 const
因为返回类型的顶级 cv 限定符是 ignored如果返回的类型是非类类型。
g++ 甚至使用 -Wextra
warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
这可以通过使用 C++14 的 decltype(auto)
来演示。与 auto
不同,decltype(auto)
不会丢弃引用和顶级 cv 限定符。如果您通过添加以下行来修改示例,代码仍将编译,证明 temp
不是 const
指针。
decltype(auto) temp = myClass.test();
static_assert(std::is_same<const int*, decltype(temp)>{}, "");
另一方面,如果 test()
返回一个具有顶级 cv 限定符的类类型的对象,那么 auto
仍然会丢弃 const
,但 decltype(auto)
不会。
关于c++ - 返回指向 const 数据成员的 const 指针和 'auto' 关键字。有点迷茫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30227277/