对象/对象指针返回(local stack\heap\temp对象)

本文通过具体的C++代码示例,详细探讨了不同情况下类的构造函数和析构函数的调用时机,特别是在使用堆内存分配和局部变量返回时的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
using namespace std;
class Base
{
      public:
             const int b;
             Base():b(10)
             {
                   cout<<"Base"<<endl;
             }
             Base(const Base & ba):b(ba.b)
             {
                 cout<<"cpBase"<<endl;
             }
             void Disp()
             {
                  cout<<this->b<<endl;
             }
             ~Base()
             {
                  cout<<"~Base"<<endl;
             }
};

Base* f()
{  
   Base *pBase=new Base();//pBase 用new分配,是heap型数据,函数调用完不会自动析构。
   return pBase;
}

Base g()//这种情况类下,bs也是local stack型数据。 函数调用完会自动析构bs。 
{
  Base bs;
  return bs;
}
 
Base h(Base h)//这种情况类下,h也是local stack型数据。 并且在Base h=b时还会调用拷贝构造函数。 函数调用完会自动析构h. 
{
     return h;
}

int main()
{
    f();
    Base d = g();//理论上应该调用构造函数的,devc++中没用调用拷贝构造函数。 如果此行代码只是: g();则相当于const Base temp = g();也不调用拷贝构造函数。 
    Base b; 
  //h(b);//等价于const Base temp = h(b);在语句结束后,temp就析构了。 调用了两次拷贝构造函数,ba=b一次,temp=ba一次。 
    Base c=h(b); 
    getchar();
    return 0;
}//main函数中的local stack型对象都会在这里自动释放

在vc6.0下的运行结果:在调用Base d=g()的时候,理论上是应该调用拷贝构造函数的,VC60下的运行结果正确。

在devc++下运行的结果:运行结果不合理。Base d=g()的时候没有调用拷贝构造函数。



如果在对Base d=g()修改,改成g();那么如下:

#include<iostream>
using namespace std;
class Base
{
      public:
             const int b;
             Base():b(10)
             {
                   cout<<"Base"<<endl;
             }
             Base(const Base & ba):b(ba.b)
             {
                 cout<<"cpBase"<<endl;
             }
             void Disp()
             {
                  cout<<this->b<<endl;
             }
             ~Base()
             {
                  cout<<"~Base"<<endl;
             }
};

Base* f()
{  
   Base *pBase=new Base();//pBase 用new分配,是heap型数据,函数调用完不会自动析构。
   return pBase;
}

Base g()//这种情况类下,bs也是local stack型数据。 函数调用完会自动析构bs。 
{
  Base bs;
  return bs;
}//析构bs
 
Base h(Base h)//这种情况类下,h也是local stack型数据。 并且在Base h=b时还会调用拷贝构造函数。 函数调用完会自动析构h. 
{
     return h;
}//析构h

int main()
{
    f();
    g();//如果此行代码只是: g();则相当于const Base temp = g();temp 在此行语句结束就调用析构函数。
    Base b; 
  //h(b);//等价于const Base temp = h(b);在语句结束后,temp就析构了。 调用了两次拷贝构造函数,ba=b一次,temp=ba一次。 
    Base c=h(b); 
    getchar();
    return 0;
}//main函数中的local stack型对象都会在这里自动释放,而new的需要手动delete。
结果:temp是系统自动创建的临时对象,在调用语句结束时,就自动析构了。而手动创建的接收对象Base d则在函数结束时自动析构(local stack对象)。如果是heap对象,那么无语是temp还是超过了函数作用域,都不会析构,需要用delete进行手动删除操作。除非整个程序结束(整个程序关闭),编译器自动释放资源,但是不调用析构函数,如上例中的f()调用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值