C++03:论类的构造函数和析构函数
一、构造函数(constructors)
构造函数命名与类名完全相同,它没有返回值,也不能用void修饰
构造函数不能被直接调用,必须通过创建对象时才会自动调用
1.无参构造函数
默认构造函数必须是无参构造函数
class Test{
public:
Test(){} //默认构造函数
}
Test t; //默认调用无参构造函数
Test t(); //错误,不能加括号,这表示函数
2.带参构造函数
3.初始化列表构造函数
Test::Test(int a):A(a)
{
}
//等同于下面
Test::Test(int a)
{
this->A=a;
}
4.拷贝构造函数
(1)浅拷贝
//如果没写拷贝构造函数,系统会默认一个拷贝构造函数,把各个成员属性复制过去
class Test{
public:
//拷贝构造函数的特点是参数是同类对象
Test(const Test& t){
this->A=t.A;
}
};
//调用
Test T(t);
(2)深拷贝
注意:当只有类成员带有指针的时候,才有浅拷贝和深拷贝之分。如果只有变量、结构体的话,它们只能拷贝了值过去。
浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针
Test(const Test& t){
A=new int(); //另外分配内存给另一个对象,如果同时指向相同的指针地址,会导致析构两次
*A=*(t.A);
}
Test(const Test& t){
A=new char(20);
memcpy(A,t.A,strlen(t.A));
}
二、析构函数(destructors)
析构函数无参数,无返回值,名字与类名相同,前面加个~
三、函数默认初始化
//这个主要是用在有时候调用这个函数需要这个参数,有时候不需要这个参数
void A(int a,int b=0){
}
四.调用顺序
(1)析构函数不加virtual
在构造一个子类对象的时候,先调用基类的构造函数,此时子类成员还没有初始化,虚函数不起作用.再调用子类的构造函数
在析构一个子类对象的时候,先调用子类的析构函数,再调用基类的析构函数
//TestMain.h
class A{
public:
A(){
cout<<"A+"<<endl;
}
~A(){
cout<<"A-"<<endl;
}
}
class B:public A{
public:
B(){
cout<<"B+"<<endl;
}
~B(){
cout<<"B-"<<endl;
}
}
//TestMain.cpp
int main(){
A* a=new A(); //输出A+ A-
delete a;
B* b=new B(); //输出A+ B+ B- A-
delete b;
A* a=new B(); //输出A+ B+ A-
delete a;
system("pause");
return 0;
}
(2)析构函数加virtual
如果父类析构函数加上virtual,那么动态绑定子类的析构函数也会一起进行调用
//TestMain.h
class A{
public:
A(){
cout<<"A+"<<endl;
}
~A(){
cout<<"A-"<<endl;
}
}
class B:public A{
public:
B(){
cout<<"B+"<<endl;
}
~B(){
cout<<"B-"<<endl;
}
}
//TestMain.cpp
int main(){
A* a=new A(); //输出A+ A-
delete a;
B* b=new B(); //输出A+ B+ B- A-
delete b;
A* a=new B(); //输出A+ B+ B- A-
delete a;
system("pause");
return 0;
}
(3)构造函数不能加virtual

浙公网安备 33010602011771号