您的位置:首页 > 编程语言 > C语言/C++

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

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

  stock.h  

#include <iostream>
#include <string.h>
class Stock{
private:
char m_company[30];
int m_stock_num;
float m_stock_price;
float total_price;
float stock_sum(){total_price= m_stock_num*m_stock_price;}

public:
int get_stock(char *company,int stock_num,float stock_price);
void increase(int num,float price);
void sell(int num,float price);
void update_price(float price);
void print_stock_info();
friend Stock plus1(int stock_num,Stock t);
Stock operator+(Stock t);
Stock(char *p,int num,float price);
Stock();
~Stock();
};

Stock::Stock(char *company,int stock_num,float stock_price)
{
int len=strlen(company);
strncpy(m_company,company,len+1);
m_stock_num=stock_num;
m_stock_price=stock_price;
stock_sum();

}

Stock::Stock()
{
m_stock_num=0;
m_stock_price=0;
stock_sum();
std::cout<<"hello boy"<<std::endl;
}

Stock::~Stock()
{
std::cout<<"good bye"<<std::endl;

}

Stock plus1(int stock_num,Stock t)
{
Stock total;
total.m_stock_num=stock_num+t.m_stock_num;
return total;

}

inline Stock Stock::operator+(Stock t)
{
Stock total;
total.m_stock_num=m_stock_num+t.m_stock_num;
total.total_price=total_price+t.total_price;
return total;
}

inline int Stock::get_stock(char * company,int stock_num,float stock_price)
{
int len=strlen(company);
if (len>30)
return false;
strncpy(m_company,company,len+1);
m_stock_num=stock_num;
m_stock_price=stock_price;
stock_sum();
return true;
}

void Stock::increase(int num,float price)
{
m_stock_num=m_stock_num+num;
m_stock_price=price;
stock_sum();
}

void Stock::sell(int num,float price)
{
if(num>m_stock_num)
m_stock_num=0;
else
m_stock_num=m_stock_num-num;

m_stock_price=price;
stock_sum();
}
void Stock::update_price(float price)
{
m_stock_price=price;

}
void Stock::print_stock_info()
{
std::cout<<m_stock_num<<std::endl;
std::cout<<total_price<<std::endl;
}


  stock.cpp  

#include "stock.h"
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char *p;
p=new char[100];
strcpy(p,"baidu");
Stock object[4];
object[0].get_stock(p,100,2.3);
object[1].get_stock(p,100,2.3);
object[2]=object[0]+object[1];
object[2].print_stock_info();
object[3]=plus1(100,object[2]);
object[3].print_stock_info();
return true;

}


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

  返回对象,



返回对象引用,



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


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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: