请考虑以下代码。它定义了一个类Test
,其中包含成员变量int &m
和成员函数Print()
,用于打印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)
更改为以下
Test::Test(int n) : m(n) {cout << "Constructing\t" << n << "\t" << &n << endl;};
我改为
Constructing 2 0x7ffc233ef15c
Constructing 2 0x7ffc233ef15c
Printing.... 2 0x7ffc233ef15c
Printing.... 32597 0x7ffc233ef15c
为什么m
在32597
中的值为test2
?我看到两个m
对象Test
和test1
之间test2
的地址现在相同但我不确定为什么要更改构造函数以输出值和地址它的输入n
会影响m
用于实例化的变量n
的值或地址。
答案 0 :(得分:4)
您正在存储对参数n
的引用,并且n
的生命周期在构造函数完成执行时结束。
在该点之后对m
的任何使用都是未定义的,因为它引用的对象不再存在。
你的程序似乎做了一些似乎合理的事情,或者它可能做了一些奇怪的事情,但它不是一个有效的C ++程序。
答案 1 :(得分:1)
您正在通过副本传递n
。
构造函数正在创建对副本的引用。
调用构造函数后副本消失。
由于副本已消失,因此引用未定义。
在构造函数int& n
中创建参数,如Test(int& n)
。