常量引用数据成员

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常量引用数据成员相关的知识,希望对你有一定的参考价值。

假设我们有一个具有常量引用数据成员的结构。

struct A {
    A() : i{5} {}
    const int& foo() const { return i; }
    const int& i;
};

你知道为什么整数5的输出是不同的吗?

A a{};
std::cout << a.i << std::endl;
std::cout << a.foo() << std::endl;

5
-858993460
答案

代码格式不正确。你正在从文字i初始化5,这需要一个临时对象被构造然后绑定到i。当构造函数退出时,临时将被销毁,然后i变得悬空,任何取消引用它后来都会导致UB,意味着一切皆有可能。

从标准,[class.base.init]/8

绑定到mem-initializer中的引用成员的临时表达式格式不正确。 [实施例:

struct A {
  A() : v(42) { }   // error
  const int& v;
};

- 结束例子]

顺便说一句:由于标准声明它的格式不正确,编制者需要为它发出诊断。 gcc(给出警告)和clang(给出错误)的行为都是一致的;如果VS2017没有发出任何诊断,那么它就不符合标准。

另一答案

使用constant值而不是literal

这是自Class::Class() : member{arg1, arg2, ...} {...以来的c++11直接列表初始化。

试试这个 :

 struct A {
    const int t = 5;
    A() : i{ t } { }
    const int& foo() const { return i; }
    const int& i;
};

int main()
{
    A a{};
    std::cout << a.i << std::endl;
    std::cout << a.foo() << std::endl;

    return 0;
}

以上是关于常量引用数据成员的主要内容,如果未能解决你的问题,请参考以下文章

java内存分配(堆栈常量池)

Java中,包的概念常量静态成员继承

测试页面

通过值或常量引用传递给函数?

五万字读懂c++

五万字读懂c++