200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > C++析构函数与构造函数深拷贝浅拷贝(C++初学面向对象编程)

C++析构函数与构造函数深拷贝浅拷贝(C++初学面向对象编程)

时间:2018-09-16 00:32:31

相关推荐

C++析构函数与构造函数深拷贝浅拷贝(C++初学面向对象编程)

文章目录

一、析构函数二、C++默认生成的函数三、构造与析构的调用顺序四、构造函数的浅拷贝五、构造函数的深拷贝

一、析构函数

1、析构函数的作用

对象消亡时,自动被调用,用来释放对象占用的内存空间。

2、属性特点

(1)名字与类名相同

(2)在前面需要加上"~"

(3)无参数,无返回值(也不能加void)

(4)一个类最多只有一个析构函数

(5)不自定义析构函数C++会生成默认析构函数

二、C++默认生成的函数

在默认情况下,定义一个C++类都会默认生成以下三个函数:

默认构造函数(无参,函数体为空)默认析构函数(无参,函数体为空)默认拷贝构造函数(对类中非静态成员进行简单值拷贝)

注意:

若自定义了拷贝构造函数,将不再提供任何构造函数。

若自定义了普通构造函数,将不会提供默认构造函数,但还是会提供默认拷贝构造函数。

三、构造与析构的调用顺序

构造函数是先定义的先调用,而析构函数是先定义的后调用,类似于“栈”存储结构。

class Test{int id;public:Test(int i){id = i;}~Test(){cout<<"ID: "<<id<<" 已析构对象内存空间"<<endl;};};Test t0(0); //最先创建的对象,最后释放void Func(){static Test t1(1);//创建静态对象,会在整个程序结束时自动释放Test t2(2); //在Func结束时自动释放cout<<"-----Func-----"<<endl;}int main(){Test t3(3);t3 = 10;//类型转换构造函数,这里会创建临时对象,将int型转成Test类型对象,在赋值结束后,临时变量销毁cout<<"------主函数开始-------"<<endl;{Test t4(4); //花括号代表作用域,不需要等到main方法结束就释放了}Func();//进入Func函数cout<<"------主函数结束-------"<<endl;return 0;}

四、构造函数的浅拷贝

就是构造函数只进行简单的值拷贝。

/*浅拷贝*/#include <iostream>#include<string.h>#include<stdlib.h>using namespace std;//定义一个类Person class Person{private:char *m_name; //私有成员数据中定义个指针 int m_num;public: //共有成员接口 Person() //普通无参构造函数 {m_name = NULL; //在构造函数中将指针指向空 m_num = 0;cout << "已调用无参构造..." << endl;}Person(char *name,int num) //普通有参构造函数 {//为m_name重新申请空间m_name = (char *)calloc(1,strlen(name)+1); //新空间大小刚好为name的长度 if(m_name == NULL) //若私有成员指针仍指向空地址,则输出构造失败 {cout<<"构造失败"<<endl;}cout<<"-->已经申请好空间"<<endl; //否则提示空间申请成功 strcpy(m_name,name); //将传入有参构造的参数指针赋值给成员指针 m_num = num; cout<<"已调用有参构造..."<<endl;}~Person() //定义析构函数 {if(m_name != NULL) //若成员指针指向空,表示空间已被释放 {cout<<"m_name的空间已被释放"<<endl;free(m_name); //否则手动释放内存空间 m_name = NULL;}cout<<"析构函数调用结束..."<<endl;}void showPerson(){cout << "m_name = " << m_name << ", m_num = " << m_num << endl;}};//定义有参构造的接口测试函数 void demo1(){Person p1("Chung", 42607); //实例化p1对象,调用有参构造函数 p1.showPerson(); //调用成员函数输出p1的信息 // 浅拷贝Person p2= p1; //调用系统的默认拷贝构造(单纯的值拷贝)}//定义无参构造的接口测试函数 void demo2(){Person p3; //实例化p3对象,调用无参构造函数p3.showPerson(); //输出p3的信息//浅拷贝Person p4= p3; //简单的值拷贝 }//主函数定义 int main(int argc, char *argv[]){//demo1(); //测试开始 ,有参构造 demo2(); //无参构造 return 0;}

(1)测试demo1

(2)测试demo2

只调用到一半就出错结束了。

五、构造函数的深拷贝

就是通过自定义,拷贝构造函数,完成深拷贝动作,能够将数值和地址都拷贝进去。

#include <iostream>#include<string.h>#include<stdlib.h>using namespace std;//定义一个类Person class Person{private:char *m_name; //私有成员数据中定义个指针int m_num;public:Person() //普通无参构造函数 {m_name = NULL; //在构造函数中将指针指向空 m_num = 0;cout << "已调用无参构造..." << endl;}Person(char *name,int num) //普通有参构造函数 {//为m_name重新申请空间m_name = (char *)calloc(1,strlen(name)+1); //新空间大小刚好为name的长度 if(m_name == NULL) //若私有成员指针仍指向空地址,则输出构造失败 {cout<<"构造失败"<<endl;}cout<<"-->已经申请好空间"<<endl; //否则提示空间申请成功 strcpy(m_name,name); //将传入有参构造的参数指针赋值给成员指针 m_num = num; cout<<"已调用有参构造..."<<endl;}//自定义拷贝构造函数 Person(const Person &p)//p是一个引用类型,括号内相当于Box p=b1{cout << "--------------------拷贝构造函数----------------------" << endl;m_name= (char *)calloc(1, strlen(p.m_name)+1); //在拷贝构造函数中重新申请空间,就能够实现地址的拷贝 cout << "空间已被申请" << endl;strcpy(m_name, p.m_name); //将引用对象常量下的m_name拷贝到私有成员数据m_name里 m_num= p.m_num;cout << "--------------------拷贝构造函数----------------------" << endl;}~Person() //定义析构函数 {if(m_name != NULL) //若成员指针指向空,表示空间已被释放 {cout<<"m_name的空间已被释放"<<endl;free(m_name); //否则手动释放内存空间 m_name = NULL;}cout<<"析构函数调用结束..."<<endl;}void showPerson(){cout << "m_name = " << m_name << ", m_num = " << m_num << endl;}};//定义有参构造的测试函数 void demo1(){Person p1("Chung", 42607);p1.showPerson();//通过自定义 拷贝构造函数 完成深拷贝动作Person p2= p1;}//定义无参构造的测试函数 void demo2(){Person p3;//p3.showPerson();//通过自定义 拷贝构造函数 完成深拷贝动作Person p4= p3;p4.showPerson();}//定义主函数 int main(int argc, char *argv[]){demo1(); //调用测试函数 //demo2();return 0;}

(1)测试demo1

(2)测试demo2

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。