这里,先不得不说c++的内存分配存储区中的两个——栈和堆
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量(变量超过作用域后自动回收)、函数参数等。在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用。和堆一样,用户栈在程序执行期间可以动态地扩展和收缩。
堆,就是那些由 new 分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个 new 就要对应一个 delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。堆可以动态地扩展和收缩。
拿程序来说明下(程序一牵涉到析构函数,程序二牵涉到析构函数和拷贝构造函数)
程序一:
#include <iostream>
using namespace std;
class A{
int a;
public :
A(int i)
{
a=i;
cout << a << " contruction!" << endl;
}
public :
~A()
{
cout << a << " dertruction!" << endl;
}
public :
void print()
{
cout << a << endl;
}
};
void main(){
A ob(3);
ob=5;
ob.print();
ob=A(12);
ob.print();
}
输出:
3 contruction!(调用构造函数 相当于new)
5 contruction!(调用构造函数,相当于ob=A(5);建立了一个临时对象然后再给b,这个对象作用域就在此句话中,因此此句话结束,该对象所占内存自动释放)
5 dertruction!
5(销毁的是临时对象,ob没回收)
12 contruction!
12 dertruction!(和上面一样)
12
12 dertruction!(程序结束,自动回收栈的内容)
程序2:
#include <iostream>
using namespace std;
class TP{
private :
int a,b;
public :
TP(int x,int y){
a=x;
b=y;
}
TP(TP &);
~TP(){
cout << "destructor" << a << " " << b << endl;
}
int aa(){
return a;
}
int bb(){
return b;
}
};
TP:: TP(TP &p)
{
a=p.a;
b=p.b;
cout << "copy constructor" << a << " " << b << endl;
}
TP fun(TP q)
{
cout << "OK1" << endl;
int a,b;
a=q.aa()+10;
b=q.bb()+20;
TP r(a,b);
cout << "OK2" << endl;
return r;
}
void main(){
TP m(10,20),h(0,0);
TP n(m);
h=fun(n);
cout << "h=" << h.aa() << " " << h.bb() << endl;
}
程序输出:
copy constructor10 20(此句是main函数第二句的执行结果,调用了拷贝构造函数)
copy constructor10 20(fun()函数调用时形参和实参的结合会调用拷贝构造函数)
OK1
OK2
copy constructor20 40(函数返回值是类的一个对象,也会调用到类的拷贝函数)
destructor20 40
destructor10 20(fun函数执行完毕,因而销毁函数内部的变量,因为入栈顺序不同,所以才有这两个输出结果)
destructor20 40(h=fun(n);fun函数有返回一个临时对象的销毁,)
h=20 40
destructor10 20(销毁n)
destructor20 40(销毁h)
destructor10 20(销毁m)(程序执行完毕,自动销毁栈里的变量,先进后出)
最后说下拷贝构造函数何时调用:
1.当用类的一个对象初始化该类的另一个对象时.
2 .如果函数的形参是类的对象,调用函数时,进行形参和实参结合时.
3 .如果函数的返回值是类的对象,函数执行完成返回调用者时.
4.需要产生一个临时类对象时。