C++ 理解此代码段的行为:所引用Int的打印值和地址不同

C++ 理解此代码段的行为:所引用Int的打印值和地址不同,c++,reference,C++,Reference,考虑以下代码。它使用成员变量int&m和成员函数Print()定义一个类Test,该函数打印m的值和地址 #include <iostream> using namespace std; class Test { public: int &m; Test(int n); void Print(); }; Test::Test(int n) : m(n) {}; void Test::Print() {cout &l

考虑以下代码。它使用成员变量
int&m
和成员函数
Print()
定义一个类
Test
,该函数打印
m
的值和地址

#include <iostream>

using namespace std;

class Test
{
    public:
        int &m;
        Test(int n);
        void Print();
};

Test::Test(int n) : m(n) {};
void Test::Print() {cout << m << "\t" << &m << endl; };

int main()
{
    int a = 2;
    Test test1(a);
    Test test2(a);
    test1.Print();
    test2.Print();
    return 0;
}
Printing....    2       0x7ffd2744cf0c                                                                                                                                              
Printing....    2       0x7ffd2744cf08                                                                                                                                              
如果我将构造函数
Test(int n)
更改为以下内容

Printing....    2       0x7ffd2744cf0c                                                                                                                                              
Printing....    2       0x7ffd2744cf08                                                                                                                                              
Test::Test(int n) : m(n) {cout << "Constructing\t" << n << "\t" << &n << endl;};

为什么
m
test2
中有值
32597
?我看到
m
的地址现在在两个
Test
对象
test1
test2
之间是相同的,但我不确定为什么更改构造函数以输出其输入
n
的值和地址会影响
n
所使用的变量
m
的值或地址实例化。

您正在存储对参数
n
的引用,并且
n
的生命周期在构造函数完成执行时结束

Printing....    2       0x7ffd2744cf0c                                                                                                                                              
Printing....    2       0x7ffd2744cf08                                                                                                                                              
在该点之后使用
m
是未定义的,因为它所指的对象不再存在

Printing....    2       0x7ffd2744cf0c                                                                                                                                              
Printing....    2       0x7ffd2744cf08                                                                                                                                              

<>你的程序可能看起来是合理的,或者它可能做一些奇怪的事情,但是它不是一个有效的C++程序。

你正在通过复制> <代码> n>代码>p>
Printing....    2       0x7ffd2744cf0c                                                                                                                                              
Printing....    2       0x7ffd2744cf08                                                                                                                                              
构造函数正在创建对副本的引用

Printing....    2       0x7ffd2744cf0c                                                                                                                                              
Printing....    2       0x7ffd2744cf08                                                                                                                                              
调用构造函数后,副本将消失

Printing....    2       0x7ffd2744cf0c                                                                                                                                              
Printing....    2       0x7ffd2744cf08                                                                                                                                              
由于副本已消失,引用未定义

Printing....    2       0x7ffd2744cf0c                                                                                                                                              
Printing....    2       0x7ffd2744cf08                                                                                                                                              

将构造函数中的参数设置为
int&n
Test(int&n)

中的参数相同。如果在相对简单的代码(如您的代码)中有一个奇怪的值,您可以确定它是未定义的行为,而不是某个地方的逻辑错误。@raket1111是的,我认为这是未定义的行为,因为当我运行代码时,
test2
中的
m
是随机的。但这确实是我编写的第一个C++代码,我不明白为什么改变<代码>测试()//>使行为不被定义。我的理解是添加到
Test()
cout
语句不会改变
n
m
。对发生的事情有什么想法吗?你知道,这是没有定义的原因。如果你加上
inta=9在代码结束时,您的计算机将爆炸。谁知道呢P@Rakete1111哈,我不太喜欢C++,但是我听说过重写内存的危险。也许我会尝试一下,一旦我知道它可能会做什么。感谢你的回应。您能否简要解释一下为什么
m
似乎是在初始代码段中定义的,因为它为两个
Test
对象都输出
2
?不知何故,添加<代码> CUT<代码> > <代码>测试()>代码>更改构造函数的生存期?您不能通过检查C++程序的行为来判断它是否未定义。可能发生的情况是,当您读取“死”对象时,它的值尚未被覆盖,但这只是运气不好。
Printing....    2       0x7ffd2744cf0c                                                                                                                                              
Printing....    2       0x7ffd2744cf08