c++中构造函数 、析构函数的作用域详解

  我们知道,在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