如何让C++函数返回值死心塌地为你工作

 更新时间:2018年01月20日 10:40:40   作者:kwsy2008  
这篇文章主要介绍了如何让C++函数返回值死心塌地为你工作,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

本文主要研究的是C++函数返回值,你必须注意的问题,下面进入正题。

C++太繁杂了,先接触C++后接触python这样的语言,你就再也不想碰它,因为,就连一个函数返回值都一大堆的说道,这里面的玄机,连工作三年的C++熟手都未必能准确的理解和运用。

归根结底,C++所面临的问题要求它提供各种各样的机制以保证性能,也许,这辈子也见不到C++能安全有效的自己进行内存垃圾回收。。。。。

老程序猿都会提醒菜鸟,注意函数的返回值,因为,很可能,你的函数返回的数据在后续的使用中会出错。那么函数在返回值时要注意什么呢?

本篇博客尝试用最简练的普通大白话,讲解函数返回值的问题。

C++把内存交给了程序猿,但是,请你注意,它可没把所有的内存都交给你,交给你的只是堆上的内存,也就是你通过malloc函数 和new 关键字申请来的内存,除了这些内存以外,其他的内存,你最好别碰,最好别碰,最好别碰,重要的事情说三遍。

如果你的函数返回值在后续使用中出错了,尤其是返回函数内的局部变量这种事情,那么,基本可以肯定,你碰了不该碰的内存。这时候,你会觉得自己很冤枉啊,我没有啊。但事实是,没有冤枉你,所以,为了不被bug检察院起诉你,作为一个C++程序猿,你必须学会甄别那些内存是能碰的,那些内存是不能碰的。

char *pstr = "This is the buffer text";  
return pstr; 

如果你的函数是这么写的,那么恭喜你,返回正确,因为这个pstr指向的是常量存储区,这里的内存,你是可以碰的,但是注意,这个碰,仅仅是读,你想修改,那是万万不可以的。

char buffer[] = "This is the buffer text";  
return buffer; 

如果你的函数是这么写的,那么恭喜你,等着bug联邦检察院起诉你吧。这里的buffer指向的是栈上内存,这个,就是你碰不得的,前面的pstr就好比公园,公园嘛,大家都可以来玩,但是你不能把公园里的假山拆了,你也不能把公园里的树砍了,你只能是来玩,不能修改它,栈上的内存,就好比是私家花园,你一个外人,是不能进去的。那么怎么甄别的,方法倒也简单,你见到带中括号的,就应该明白,这东西是栈上的,出了这个函数,你就别想再碰的,你只要敢碰,bug联邦检察院就会起诉你。

static char buffer[] = "This is the buffer text";  
return buffer; 

如果你的函数是这么写的,那么恭喜你,返回正确,可是刚才不是明明说,这里是私家花园嘛,没错,但是你注意看,前面还加了一个static,只要加了这个关键字,就相当于说国家把这个私家花园征用了,那么,它就从私家花园变成了静态存储区里的一个小花园,静态存储区里的内存,国家说,静态存储区对外开放,你们都可以来。

函数返回的都是值拷贝,栈上的内存,在函数结束的时候,都会被收回。在函数内部,你可以碰栈上的内存,那是因为这个时候你是在栈的家里做客,那他们家的内存小花园当然允许你访问,可是函数结束了,就相当于你离开了栈的家,栈把内存小花园的门关上了,你怎么可以进去,你进去了,就会被bug联邦法院起诉!

但是呢,总有一些奇怪的现象让你以为你可以在函数结束后仍然可以访问栈上的内存。

我们定义一个结构体

struct person 
{ 
  int age; 
} 

写一个函数

person* getperson2() 
{ 
  person p; 
  p.age = 99; 
  return &p; 
} 

在得到函数的返回值以后,你可以输出对象的年龄

person *p2 = getperson2(); 
cout<<p2->age<<endl; 

你会发现,这段代码居然可以正确执行!在函数getperson2内部,p这个变量是局部变量,必然是在栈上申请的,返回的是&p,这不就是栈上的内存地址么,那为啥在函数外部,却仍然可以输出age呢?

虽然,函数结束后,对象被销毁,但是销毁的不够彻底,似乎计算机在管理内存时也不需要那么彻底的销毁一个对象,你之所以能输出age,那是因为那个区域,没有被彻底销毁,这一小块的内存(存储age的4个byte)没有发生变化。你可以暂时的碰这块内存,但迟早是要出问题的,如果某一刻,计算机打算用这块内存,发现你在非法使用,那么必然会报警,然后bug联邦检察院会起诉你。

为了让问题更透明一些,我们修改一下结构体

struct person 
{ 
  int age; 
  char* name; 
  person() 
  { 
    name = new char(10); 
    strcpy(name,"sheng"); 
  } 
  ~person() 
  { 
    name = NULL; 
  } 
}; 
person* getperson2() 
{ 
  person p; 
  p.age = 99; 
  return &p; 
} 
person *p2 = getperson2(); 
cout<<p2->age<<endl; 
cout<<p2->name<<endl; 

这一次,函数结束后,对象的销毁要比上一次彻底的多,虽然,age的区域还是没有被彻底销毁,但是name区域被彻底销毁了,如果你访问name的区域,就必然出错,这就好比啊,私家花园关门了,可是花园好大的,所以不是每一处都安装了摄像头和报警器,比如age这片区域,所以,你偷偷的从age这个区域溜进去时,花园的主人没发现,直到花园的巡防大队到age区域巡防时,发现你竟然在这里偷偷菜花,结果就是把你打的崩溃了。而name这边区域,在~person这个析构函数中安装了摄像头和报警器,你只要来,就立刻报警,然后把你打的崩溃。

千言万语,汇成一句话,函数不要返回指向栈的内存地址,切记,是地址,别被吓的所有的函数内的变量都不敢返回,只要不是栈的内存地址,你尽管放心的返回。

以上就是本文关于如何让C++函数返回值死心塌地为你工作的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • C++中static修饰符的详解及其作用介绍

    C++中static修饰符的详解及其作用介绍

    这篇文章主要介绍了C++中static修饰符的详解及其作用介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • VS中的scanf_s函数和scanf用法及说明

    VS中的scanf_s函数和scanf用法及说明

    这篇文章主要介绍了VS中的scanf_s函数和scanf用法及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Qt无边框窗口拖拽和阴影的实现方法

    Qt无边框窗口拖拽和阴影的实现方法

    这篇文章主要给大家介绍了关于Qt无边框窗口拖拽和阴影的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • C语言移除元素的三种思路讲解

    C语言移除元素的三种思路讲解

    这篇文章主要介绍了C语言移除元素的三种思路,总的来说这并不是一道难题,那为什么要拿出这道题介绍?拿出这道题真正想要传达的是解题的思路,以及不断优化探寻最优解的过程。希望通过这道题能给你带来一种解题优化的思路
    2022-10-10
  • C++堆排序算法实例详解

    C++堆排序算法实例详解

    这篇文章主要介绍了C++堆排序算法,简单分析了堆排序算法的原理并结合实例形式分析了C++实现堆排序的具体操作技巧,需要的朋友可以参考下
    2017-08-08
  • 通过一个小例子来简单理解C语言中的内存空间管理

    通过一个小例子来简单理解C语言中的内存空间管理

    这篇文章主要介绍了通过一个小例子来简单理解C语言中的内存空间管理,涉及到堆和栈等数据结构的基本知识,需要的朋友可以参考下
    2015-11-11
  • C++实现主机字节序和网络字节序转换示例

    C++实现主机字节序和网络字节序转换示例

    这篇文章主要为大家介绍了C++实现主机字节序和网络字节序转换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • C++虚函数注意事项

    C++虚函数注意事项

    这篇文章主要给大家分享了EC++虚函数注意事项,
    2022-01-01
  • 详解C++-二阶构造模式、友元

    详解C++-二阶构造模式、友元

    这篇文章主要介绍了C++-二阶构造模式、友元,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • C语言时间函数之mktime和difftime详解

    C语言时间函数之mktime和difftime详解

    这篇文章主要为大家详细介绍了C语言时间函数之mktime和difftime,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一,希望能够给你带来帮助
    2022-02-02

最新评论