Pet*_*ete 18 c++ pointers const auto c++11
我最近一直在学习C++,并且今天已经介绍了const和const正确性的概念.为了更好地理解这个理论,我一直在编写一系列简单的程序来确保我理解这个概念.我以为我理解了一切,但是当在其中一个程序中使用auto关键字时,我似乎有点卡住了.
为了测试我理解const指针是如何工作的,我编写了一个简单的程序.我不打算发布整件事,因为它只有两部分是相关的.我有一个类型为int的const数据成员的类:
const int tryToChangeMe;
Run Code Online (Sandbox Code Playgroud)
在这个类中,我还有一个成员函数,它返回一个指向上面的const int的const指针:
const int* const MyClass::test()
{
return &tryToChangeMe;
}
Run Code Online (Sandbox Code Playgroud)
在我的main函数中,然后调用上面的函数,使用auto关键字.为了测试我认为我对const的了解是正确的,然后尝试通过指针重新分配tryToChangeMe变量.像这样:
auto temp = myClass.test();
*temp = 100;
Run Code Online (Sandbox Code Playgroud)
正如我所料,由于我在尝试为const变量赋值时所引起的错误,程序无法编译.但是,我不只是返回一个指针常量,我回到一个常量指针常量(至少这是我认为我做了).所以为了测试这个,我试图将指针重新分配给一个新的内存地址,相信我会得到类似的编译错误:
temp = new int;
Run Code Online (Sandbox Code Playgroud)
但令人困惑的是,该程序编译没有任何问题.通过调试器逐步调试显示,指针正在丢失其原始地址并被分配一个全新的地址.想知道发生了什么,我偶然发现了删除auto关键字并将其替换为变量的完整类型:
const int* const temp = myClass.test();
Run Code Online (Sandbox Code Playgroud)
再次测试所有内容后,结果与预期一致,这次我无法将指针重新分配给新地址.
毕竟,我想我的问题是,为什么?为什么auto关键字允许你绕过指针的const限定符?我做错什么了吗?
顺便说一句,我不确定它是否重要,但我正在使用Visual Studio 2015预览版
如前所述,auto忽略顶级cv限定符.阅读这篇文章,了解如何在细节auto和decltype工作.
现在,即使auto没有忽略const,在你的情况下,temp仍然不会const因为返回类型的顶级cv限定符被忽略,如果返回的类型是非类类型.
g ++甚至会产生以下警告 -Wextra
警告:在函数返回类型[-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)>{}, "");
Run Code Online (Sandbox Code Playgroud)
另一方面,如果test()使用顶级cv-qualifier返回类类型的对象,那么auto仍然会丢弃const,但decltype(auto)不会丢弃.
原因是auto变量不是默认的const.返回const值这一事实并不意味着必须将其赋值给const变量; 毕竟复制了该值(尽管值是指针).您也可以使用显式类型规范轻松尝试.myClass更改变量时,存储的值将不会更改,temp并且指针目标仍然存在,const因此仍然遵循常量.