CPP学习之——引用容易犯的错误(9.16)

一 概述

与指针一样,引用使用不当也会出现致命性的错误。我们知道引用是对象的别名,那么假如这个对象不存在了,使用这个对象的别名会发生什么样的后果呢?

二 代码及输出

2.1 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
using namespace std;
class A
{
private:
int x;
public:
A(int i) {i = x;}
int get() {return x;}
};
A& func() {
A a(23);
return a;

}
int main()
{
A &r = func();
cout << r.get() << endl;
return 0;
}

2.2 输出结果

1
3374512//(随机数)

2.3 说明

  • 由于对象a是局部对象,因此当函数func结束后,局部对象a也就被删除了。由于对象a消失了,所以func函数返回的其实是一个不存在的对象的别名
  • r.get();用这个不存在的对象来调用该对象的函数get,该函数会返回一个并不存在的对象的X成员。由于这个对象不存在,所以它的X成员也不存在,因此输出了一个随机数

2.4 修改后代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
using namespace std;
class A
{
private:
int x;
public:
A(int i) {x = i;}
int get() {return x;}
};
A func()
{
A a(23);
return a;
}
int main()
{
A r = func();
cout << r.get() << endl;
return 0;
}

2.5 修改后输出结果

1
23

三 示例二

3.1 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<iostream>
using namespace std;
class A
{
private:
int x;
public:
A(int i)
{
cout << "执行构造函数创建一个对象\n";
x = i;
}
A(const A &a)
{
x = a.x;
cout << "执行复制构造函数创建对象\n";
}
~A()
{
cout << "执行析构函数!\n";
}
int get() const {return x;}
};
A func()
{
cout << "跳转到func函数中!\n";
A a(23);
cout << "对象a的地址:" << &a << endl;
return a;
}
int main()
{
A a = func();
A *r = &a;
//const A&r=func();
cout << "对象a的副本的地址:" << r << endl;
cout << r->get() << endl;
return 0;
}

3.2 输出结果

1
2
3
4
5
6
跳转到func函数中!
执行构造函数创建一个对象
对象a的地址:0x22fe30
对象a的副本的地址:0x22fe30
23
执行析构函数!

3.3 调试过程中出现的错误

3.3.1 no matching function for call to 'A::A(A)'

  • 位置:复制构造函数处
  • 解决办法:使用const修饰