【C++】 构造函数、析构函数、拷贝函数

发布时间:2026/7/15 3:16:26

【C++】 构造函数、析构函数、拷贝函数 对象的初始化和清理文章目录一、构造函数二、析构函数三、拷贝构造函数四、深拷贝与浅拷贝创建一个类C编译器会给该类自动增加至少三个函数构造函数空实现、析构函数空实现、拷贝构造函数值拷贝一、构造函数构造函数是一个特殊的成员函数。1、构造函数没有返回值也不写void函数名与类名相同2、构造函数可以有参数所以可以发生重构3、它在类实例化为对象的时候自动调用而且只会调用一次。class Person{public:Person(){//无参构造函数默认构造函数cout无参构造函数的调用endl;}Person(inta){//有参构造函数m_aa;cout有参构造函数的调用endl;}intm_a;//成员属性};如果用户自己创建有参构造函数那么编译器不会再提供默认无参构造函数但是会提供默认拷贝构造函数如果用户自己创建拷贝构造函数那么编译器不再提供其他构造函数。二、析构函数1、析构函数没有返回值也不写void函数名与类名相同函数名前面加~2、析构函数没有参数所以不能发生重构3、在对象销毁之前会自动调用析构函数而且只会调用一次。class Person{public:Person(){//无参构造函数cout无参构造函数的调用endl;}Person(inta){//有参构造函数m_aa;cout有参构造函数的调用endl;}~Person(){//析构函数cout析构函数的调用endl;}intm_a;//成员属性};三、拷贝构造函数C中拷贝构造函数调用时机通常有三种情况1、使用一个已经创建完毕的对象来初始化一个新对象。2、值传递的方式给函数参数传值3、以值方式返回局部对象class Person{public:Person(){//无参构造函数cout无参构造函数的调用endl;}Person(inta){//有参构造函数m_aa;cout有参构造函数的调用endl;}Person(constPersonp){//拷贝构造函数 用引用的方式传递m_ap.m_a;cout拷贝构造函数的调用endl;}~Person(){//析构函数cout析构函数的调用endl;}intm_a;};//1、使用一个已经创建完毕的对象来初始化一个新对象。voidtest01(){Personp1(10);Personp2(p1);//Person(p1);//编译器会认为 Person (p1) Person p1 对象声明 重定义 报错}//2、值传递的方式给函数参数传值voiddowork(Person p){p.m_age1000;}voidtest02(){Person p1;dowork(p1);//Person p p1;coutp1.m_ageendl;//形参不影响实参,输出不为1000}//3、以值方式返回局部对象Persondowork(){Person p;p.m_age1;returnp;//以值的方式返回会复制新的数据}voidtest03(){Person pdowork();coutp.m_ageendl;//输出为1}//voidmain(){//test01();test02();//test03();}四、深拷贝与浅拷贝如果类的成员属性是在堆区中开辟的那么要自己提供拷贝构造函数否则会出现浅拷贝的问题即堆区内存重复释放例如class Person{public:Person(intage,intheight){m_ageage;m_heightnewint(height);//用指针接收开辟的地址}Person(constPersonp){m_agep.m_age;//m_height p.m_height;//编译器提供的//浅拷贝假设调用拷贝构造函数Person p1 Person(p2),p2的m_height指向地址0x1000,那么拷贝的p1的m_height也指向0x1000;//在程序结束的时候先释放p1的堆区内存再释放p2的堆区内存释放的都是0x1000地址的内存导致重复释放m_heightnewint(*p.m_height);//自己提供的//深拷贝重新在堆区开辟一块内存假设此时p1的m_height指向0x2000,与p2的m_height指向的地址0x1000不同//但0x1000和0x2000存放的数据内容是一样的只是存放在不同的地址此时再释放堆区内存时p1和p2释放的是不同地址的内存不会出现重复释放}intm_age;int*m_height;};

相关新闻