C++03:论类的构造函数和析构函数
一、构造函数(constructors)
构造函数命名与类名完全相同,它没有返回值,也不能用void修饰
构造函数不能被直接调用,必须通过创建对象时才会自动调用
1.无参构造函数
默认构造函数必须是无参构造函数
1 2 3 4 5 6 7 | class Test{ public : Test(){} //默认构造函数 } Test t; //默认调用无参构造函数 Test t(); //错误,不能加括号,这表示函数 |
2.带参构造函数
3.初始化列表构造函数
1 2 3 4 5 6 7 8 9 10 | Test::Test( int a):A(a) { } //等同于下面 Test::Test( int a) { this ->A=a; } |
4.拷贝构造函数
(1)浅拷贝
1 2 3 4 5 6 7 8 9 10 11 12 | //如果没写拷贝构造函数,系统会默认一个拷贝构造函数,把各个成员属性复制过去 class Test{ public : //拷贝构造函数的特点是参数是同类对象 Test( const Test& t){ this ->A=t.A; } }; //调用 Test T(t); |
(2)深拷贝
注意:当只有类成员带有指针的时候,才有浅拷贝和深拷贝之分。如果只有变量、结构体的话,它们只能拷贝了值过去。
浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针
1 2 3 4 5 6 7 8 9 | 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)
析构函数无参数,无返回值,名字与类名相同,前面加个~
三、函数默认初始化
1 2 3 4 | //这个主要是用在有时候调用这个函数需要这个参数,有时候不需要这个参数 void A( int a, int b=0){ } |
四.调用顺序
(1)析构函数不加virtual
在构造一个子类对象的时候,先调用基类的构造函数,此时子类成员还没有初始化,虚函数不起作用.再调用子类的构造函数
在析构一个子类对象的时候,先调用子类的析构函数,再调用基类的析构函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //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; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //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,那么动态绑定子类的析构函数也会一起进行调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //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; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)