c++ - 返回指向 const 数据成员的 const 指针和 'auto' 关键字。有点迷茫

标签 c++ pointers c++11 constants auto

我最近一直在学习 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 的指针,我返回了一个指向 constconst 指针(至少我是这么认为的)做过)。因此,为了测试这一点,我尝试将指针重新分配给一个新的内存地址,并确信我会得到类似的编译错误:

temp = new int;

但相当令人困惑的是,程序编译时没有任何问题。调试器逐步显示,果然,指针丢失了它的原始地址并被分配了一个全新的地址。想知道发生了什么,我碰巧删除了 auto 关键字并将其替换为变量的完整类型:

const int* const temp = myClass.test();

再次测试所有内容后,结果与预期一致,这次我无法将指针重新分配给新地址。

毕竟我想我的问题是,为什么?为什么 auto 关键字允许您绕过指针的 const 限定符?我是不是做错了什么?

顺便说一句,我不确定这是否重要,但我正在使用 Visual Studio 2015 预览版

最佳答案

如前所述,auto 忽略顶级 cv 限定符。阅读 this article了解 autodecltype 如何工作的详细信息。

现在,即使 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) 不会。

Live demo

关于c++ - 返回指向 const 数据成员的 const 指针和 'auto' 关键字。有点迷茫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30227277/

相关文章:

c++ - C++ 中的这些 extern 声明有什么区别?

C++11 左值到右值的转换?

c++ - 为什么不能使用 constexpr 全局变量来初始化 constexpr 引用类型?

c++ - 更改C++中成员函数的地址

c++ - 从成员函数 c++ 返回指针

pointers - 为什么弱指针有用?

c++ - 在写入该变量的唯一线程中使用 memory_order_relaxed 加载原子变量是否安全?

c++ - 如果从不使用该函数,您可以在 C++ 模板函数中使用未定义的类型吗?

c++ - 将数组传递给增强 vector 元组

c++ - 为什么,如果 c++ 标准说语法不正确,g++ 允许吗?