https://stackoverflow.com/a/8523361/11862989从这个答案这个问题开始出现。我觉得很小
那个答案有问题,所以我在那里评论了但没有他的回复(我指的是回答的家伙(190K 声誉))所以我在这里问那一小部分。
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";
}
main.cpp 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";
}
main.cpp int main()
{
int x=99;
std::cout<<&x<<" "<<x<<"\n";
A a1(x);
}
输出 0x72fe0c 99
0x72fe0c 99
0x72fe0c 99
在 第二 代码,因为我们正在传递 x
的引用通过 main 由 k1
收集.现在我们传递了 k1
的引用至 i
.现在意味着 i
指的是k1
和 k1
指的是x
.间接表示i
指的是x
我对吗 ?在 第一 我认为这里的变量值
x
通过 main 传递并由变量 k1
收集然后引用 k1
传递给变量 i
.所以在这种情况下变量 i
指的是变量 k1
但变量 k
不是指变量 x
我对吗 ?我在上面提到的那个人(190K 声誉)他使用第一种方法来做到这一点,我认为他是错误的,__2nd__method 适合初始化类中对象的引用变量。我对吗 ?
最佳答案
你是对的,很好的收获。您所指的答案中的 Alok 示例有缺陷。您的示例已经显示了这一点,在此 godbolt example 中可以看到引用过时引用的未定义行为的可能后果。 .我公开了 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 没有警告。
关于c++ - 用成员初始化列表初始化类对象的引用变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67619383/