我们知道,在c++中,析构函数是在函数作用域尾部执行析构函数,从而释放对象,但是有一种情况下,析构函数作用域发生变化,请看下面的例子,定义了一个Stock类,Stock类存放在stock.h中,主调用函数在stock.cpp中。

  stock.h  

  1 #include <iostream>
  2 #include <string.h>
  3 class Stock{
  4 private:
  5    char m_company[30];
  6    int m_stock_num;
  7    float m_stock_price;
  8    float total_price;
  9    float stock_sum(){total_price= m_stock_num*m_stock_price;}
 10
 11 public:
 12    int get_stock(char *company,int stock_num,float stock_price);
 13    void increase(int num,float price);
 14    void sell(int num,float price);
 15    void update_price(float price);
 16    void print_stock_info();
 17    friend Stock plus1(int stock_num,Stock t);
 18    Stock operator+(Stock t);
 19    Stock(char *p,int num,float price);
 20    Stock();
 21    ~Stock();
 22 };
 23
 24 Stock::Stock(char *company,int stock_num,float stock_price)
 25 {
 26    int len=strlen(company);
 27    strncpy(m_company,company,len+1);
 28    m_stock_num=stock_num;
 29    m_stock_price=stock_price;
 30    stock_sum();
 31
 32 }
 33
 34 Stock::Stock()
 35 {
 36    m_stock_num=0;
 37    m_stock_price=0;
 38    stock_sum();
 39    std::cout<<"hello boy"<<std::endl;
 40 }
 41
 42 Stock::~Stock()
 43 {
 44    std::cout<<"good bye"<<std::endl;
 45
 46 }
 47
 48 Stock plus1(int stock_num,Stock t)
 49 {
 50    Stock total;
 51    total.m_stock_num=stock_num+t.m_stock_num;
 52    return total;
 53
 54 }
 55
 56
 57 inline Stock Stock::operator+(Stock t)
 58 {
 59    Stock total;
 60    total.m_stock_num=m_stock_num+t.m_stock_num;
 61    total.total_price=total_price+t.total_price;
 62    return total;
 63 }
 64
 65 inline int Stock::get_stock(char * company,int stock_num,float stock_price)
 66 {
 67    int len=strlen(company);
 68    if (len>30)
 69       return false;
 70    strncpy(m_company,company,len+1);
 71    m_stock_num=stock_num;
 72    m_stock_price=stock_price;
 73    stock_sum();
 74    return true;
 75 }
 76
 77 void Stock::increase(int num,float price)
 78 {
 79    m_stock_num=m_stock_num+num;
 80    m_stock_price=price;
 81    stock_sum();
 82 }
 83
 84 void Stock::sell(int num,float price)
 85 {
 86    if(num>m_stock_num)
 87       m_stock_num=0;
 88    else
 89       m_stock_num=m_stock_num-num;
 90
 91    m_stock_price=price;
 92    stock_sum();
 93 }
 94 void Stock::update_price(float price)
 95 {
 96    m_stock_price=price;
 97
 98 }
 99 void Stock::print_stock_info()
100 {
101    std::cout<<m_stock_num<<std::endl;
102    std::cout<<total_price<<std::endl;
103 }

  stock.cpp  

 1 #include "stock.h"
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 int main()
 6  {
 7    char *p;
 8    p=new char[100];
 9    strcpy(p,"baidu");
10    Stock object[4];
11    object[0].get_stock(p,100,2.3);
12    object[1].get_stock(p,100,2.3);
13    object[2]=object[0]+object[1];
14    object[2].print_stock_info();
15    object[3]=plus1(100,object[2]);
16    object[3].print_stock_info();
17    return true;
18
19  }

  可以看到我们声明友元函数plus1后,将object[2]对象通过构造函数传递到友元中,此时友元函数中先调用拷贝构造函数接受参数,然后调用 默认构造函数形成局部total对象,在我们完成加的动作之后,对象要返回,此时调用析构函数,但若此时我们采用引用的返回值方式 Stock &plus1(int stock_num,Stock t) ,调用同样成功,但对象被销毁了,为什么还可以被引用  而继续使用。我们来看一下两种返回方式的结果:

  返回对象,

返回对象引用,

  此时编译器应该是做过优化,因为函数的作用域结尾处,应该调用过析构函数了(从图中可以看出来,调用了5次构造函数,6次析构函数,有一次复制构造函数),所以析构 函数肯定是被执行了,但是编译器作过优化处理,使得对象依旧可以被传递,此时编译器会给出警告提示。但是在1个函数中,我们可以返回1个在函数调用结束不会被释放的对象的引用。比如外部传入的对象,比如函数所属类的成员变量等。而返回局部变量(对象引用)是很危险的,但是返回对象则是可以的,因为返因对象时会调用复制构造函数、然后才是析构函数。如果我们plus1调用传递的是引用时,此时结果为

,不会调用复制构造函数。当改为值传递后,复制构造函数又被重新调用,

转载于:https://www.cnblogs.com/hitwhhw09/p/4629783.html

c++中构造函数 、析构函数的作用域详解相关推荐

  1. python的sort方法是哪种_python中的sort方法使用详解

    Python中的sort()方法用于数组排序,本文以实例形式对此加以详细说明: 一.基本形式列表有自己的sort方法,其对列表进行原址排序,既然是原址排序,那显然元组不可能拥有这种方法,因为元组是不可 ...

  2. iOS中的HotFix方案总结详解

    iOS中的HotFix方案总结详解 相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结.iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dy ...

  3. php中this的使用技巧,JavaScript中this关键字使用方法详解

    JavaScript中this关键字使用方法详解 在面向对象编程语言中,对于this关键字我们是非常熟悉的.比如C++.C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要理解了 ...

  4. java8中的lambda表达式实用详解

    java8中的lambda表达式实用详解 1. lambda简介 ​ Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中 ...

  5. pdo mysql dsn_使用PDO构造函数连接数据库及DSN详解

    PDO是PHP 5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,什么 php_mysql.dll.php_pgsql.dll.php_m ...

  6. JDK中的Timer和TimerTask详解 目录结构: Timer和TimerTask 一个Timer调度的例子 如何终止Timer线程 关于cancle方式终止线程 反复执行一个任务 sche

    JDK中的Timer和TimerTask详解 目录结构: Timer和TimerTask 一个Timer调度的例子 如何终止Timer线程 关于cancle方式终止线程 反复执行一个任务 schedu ...

  7. python中getitem_Python类中方法getitem和getattr详解

    1.getitem 方法 使用这个方法最大的印象就是调用对象的属性可以像字典取值一样使用中括号['key'] 使用中括号对对象中的属性进行取值.赋值或者删除时,会自动触发对应的__getitem__. ...

  8. maven中强大的scope标签详解

    maven中强大的scope标签详解 本文目的   接上一篇maven的版本号version的总结及理解   当我在封装工具jar包的时候,发现有些依赖,是一定要在工具代码里使用的,比如我做的工具包里 ...

  9. python find的使用方法_Python中的rfind()方法使用详解

    Python中的rfind()方法使用详解 rfind()方法返回所在子str 被找到的最后一个索引,或者-1,如果没有这样的索引不存在,可选择限制搜索字符串string[beg:end]. 语法 以 ...

最新文章

  1. 人工神经网络背后的数学原理!
  2. 什么是停止词stopword
  3. Yii框架控制台报错: The id configuration for the Application is required
  4. php excel 导入 显示,php Excel 导入
  5. 字节跳动推“头条搜索”独立APP 安卓端已上线
  6. 阿里天池全国社保比赛心得
  7. 两周内股指见底概率大
  8. 关于_MSC_VER的说明
  9. 2014全国计算机二级visual foxpro,全国计算机等级考试二级visual_foxpro试题
  10. html5-移动端布局模板
  11. 孟云飞 :一代通才 自成家数——赵之谦的艺术人生
  12. windows修改IP命令/脚本
  13. 【3D点云】弱监督点云分割(论文解读 CVPR2020)
  14. 一个岔路口分别通向诚实国和说谎国。 来了两个人,已知一个是诚实国的,另一个是说谎国的。 诚实国永远说实话,说谎国永远说谎话。现在你要去说谎国, 但不知道应该走哪条路,需要问这两个人。请问应该怎么问?(
  15. 编程语言中,还有一种语言,那就是用中文来编程
  16. 网络安全等级保护测评高风险判定
  17. 操作系统教程第六版——第四章课后作业
  18. Redhat 6.2(64位) 及 Oracle 11.2.0.4(64位)安装随笔
  19. 计算机用户锁定无法登陆,win7引用的账户当前已锁定 且可能无法登陆怎么办怎么办-win7账户被锁定,win7解除锁定账户...
  20. 使用UCF101完成的视频动作分类识别

热门文章

  1. C++ 异常处理Demo - win32 版
  2. Flex命令行学习总结
  3. Windbg dump分析 学习总结
  4. Mysql非安装版的安装使用相关问题
  5. Python开发【第5节】【函数基础】
  6. 软工作业2:硬币游戏——代码的分析与改进
  7. 洛谷——P1106 删数问题
  8. ubuntu 桌面图标设置
  9. Linux硬件信息查看
  10. [翻译]Silverlight2 RC版本发布