1

https://stackoverflow.com/a/8523361/11862989从这个答案这个问题就出现了。我觉得那个答案有小问题,所以我在那里发表了评论,但没有得到他的回复(我指的是那个人(190K Reputation)的答案)所以我在这里问了一小部分。

1.

。H

struct A
{
    private:
        int &i;
    public:
        A(int);
};

.cpp

A::A(int k1): i(k1)   
{
    std::cout<<&k1<<" "<<k1<<"\n";
    std::cout<<&i<<" "<<i<<"\n";
}

主文件

int main()
{
    int x=99;
    std::cout<<&x<<" "<<x<<"\n";
    A a1(x);
}

输出

0x72fe0c 99
0x72fde8 99
0x72fde8 99

2.

。H

struct A
{
    private:
        int &i;  // __change__
    public:
        A(int&);
};

.cpp

A::A(int &k1): i(k1)    // __change__
{
    std::cout<<&k1<<" "<<k1<<"\n";
    std::cout<<&i<<" "<<i<<"\n";
}

主文件

int main()
{
    int x=99;
    std::cout<<&x<<" "<<x<<"\n";
    A a1(x);
}

输出

0x72fe0c 99
0x72fe0c 99
0x72fe0c 99

第二个代码中,因为我们x通过 main 传递引用,它由k1. 现在我们传递对k1to的引用i。表示 nowi指的是k1k1指的是x。意味着间接i指的x是我是对的吗?

第一个我认为这里变量的值x是通过 main 传递的,它是由 variable 收集的k1,然后引用 ofk1被传递给 variable i。所以在这种情况下,变量i是指变量k1,但变量k不是指变量x,对吗?

我在上面提到的那个人(190K Reputation)的答案他使用第一种方法来做到这一点,我认为他错了,__2nd__ 方法对于初始化类中对象的引用变量是正确的。我对吗 ?

4

1 回答 1

1

你是对的,很好的收获。您提到的答案中的 Alok 示例是有缺陷的。您的示例已经显示了它,并且可以在此godbolt 示例中看到引用过时引用的未定义行为的可能后果。我公开了 A::i 并将主要功能更改为

int main()
{
  int x = 99;
  cout << &x << " " << x << "\n";

  A a1(x);
  cout << a1.i << " " << "\n";    
  cout << a1.i << " " << "\n";    // not 99 any more!
}

示例中的输出是

0x7fff6983d4dc 99
0x7fff6983d4b4 99
0x7fff6983d4b4 99
99 
32767 

第一个输出在堆栈上创建了足够的操作来覆盖地址&a1.i,该地址当时包含本地k1

智能编译器可以检测到这一点并发出警告;确实,clang 说warning: binding reference member 'i' to stack allocated parameter 'k1' [-Wdangling-field]。gcc 10.2 不会发出警告。

于 2021-05-20T12:03:59.020 回答