#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()调用。