必须返回一个对象时,不要试图返回一个引用

《Effective c++》第23条:必须返回一个对象时不要试图返回一个引用。所有:

  1. 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用。
  2. 也不要返回函数内部用new初始化的智能指针的引用
  3. 上面两条同样适用于线程:不雅把局部对象的应用、局部指针的引用和局部智能指针的引用传递给一个不知道生命周期的线程。因为可能会出现局部对象被析构的时候,线程还在使用的情况。

必须返回一个对象时,不要试图返回一个引用,很多次遇到这句话,但是在使用的时候,还是没有注意到。返回一个对象的应用,在某种情况下,不会显示出错误,但是为以后代码的出错埋下了伏笔。

我说的某些情况下不会展示出错误,请看下面的例子:

#include <iostream>
class Test {
public:
	void print() {
		static int i = 0;
		std::cout << i++ << std::endl;
	}	
};

Test& getTest() { //获取局部对象的引用
	Test test;
	return test;
}

Test*& getPTest() { //获取局部指针的引用
	Test *ptest = new Test;
	return ptest;
}

std::shared_ptr<Test>& getShareTest() { //获取局部智能指针的引用
	std::shared_ptr<Test> sharePtr(new Test());
	return sharePtr;
}

int main(int argc, char *argv[]) {
	//以下三个例子分别执行
	Test& test1 = getTest();
	while(1) {
		test1.print();
	}
	
	Test*& test2 = getPTest();
	while(1) {
		test2->print();
	}
	
	std::shared_ptr<Test> sharePtr = getShareTest();
	while(1) {
		sharePtr->print();
	}
	return 0;
}
输出都是:
0
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(后面省略)
从上的三个小例子可以看出,局部对象的引用、局部指针的引用、局部智能指针的引用使用都没有问题,也许你会窃喜。

但是只需要修改一点点,就会发现问题:

#include <iostream>
class Test {
public:
	Test (int num) : num_(num) {}
	void print() {
		static int i = 0;
		std::cout << num_ << " " <<  i++ << std::endl;
	}
private:
	int num_;
};

Test& getTest() { //获取局部对象的引用
	Test test(10);
	return test;
}

Test*& getPTest() { //获取局部指针的引用
	Test *ptest = new Test(10);
	return ptest;
}

std::shared_ptr<Test>& getShareTest() { //获取局部智能指针的引用
	std::shared_ptr<Test> sharePtr(new Test(10));
	return sharePtr;
}

int main(int argc, char *argv[]) {
	//以下三个例子分别执行
	Test& test1 = getTest();
	while(1) {
		test1.print();
	}
	
	Test*& test2 = getPTest();
	while(1) {
		test2->print();
	}
	
	std::shared_ptr<Test> sharePtr = getShareTest();
	while(1) {
		sharePtr->print();
	}
	return 0;
}
这次的输出:
10 0
-1239546272 1
-1239546272 2
-1239546272 3
-1239546272 4
-1239546272 5
-1239546272 6
-1239546272 7
-1239546272 8
-1239546272 9
-1239546272 10
-1239546272 11
-1239546272 12
-1239546272 13
-1239546272 14
-1239546272 15
-1239546272 16
-1239546272 17
-1239546272 18
-1239546272 19
-1239546272 20
-1239546272 21(后面省略)
只输出一次正确的结果,多次执行的结果并不相同,怎么回事呢?这时候你会想到传进去的10存在哪里?栈上?那函数结束,出栈?对的!函数执行结束的时候,局部变量的作用域结束,局部变量被析构,内容出栈,所以输出的内容是垃圾值。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值