1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 构造函数和析构函数深拷贝和浅拷贝

构造函数和析构函数深拷贝和浅拷贝

时间:2020-05-30 15:40:13

相关推荐

构造函数和析构函数深拷贝和浅拷贝

在C++中能够定义和使用和类名相同的成员函数,这种和类名相同的成员函数叫做构造函数

构造函数可以有参数还可以没有参数

构造函数没有返回类型的声明

一般情况下C++编译器会自动调用构造函数

当然也可以手动的去调用构造函数

C++中的类也可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数语法: ~className()

析构函数没有参数也没有任何返回类型的声明

析构函数在对象销毁之前被调用

析构函数的调用机制,C++编译器自动调用

构造函数也是成员函数只不过是一种特殊的成员函数

构造函数和析构函数的作用

通过结果可以看出来构造函数和析构函数的执行过程是构造函数和声明的顺序相同,析构函数和声明的顺序相反。

#define _CRT_SECURE_NO_WARNINGS#include <iostream>using namespace std;class Test{public:Test() //构造函数{p = (char *) malloc(100); a =10;strcpy(p ,"aaaaaaaddjdjj");cout << "这是一个构造函数" << endl;}void printP(){cout << p << endl;cout << a << endl;}~Test(){if ( p != NULL){free(p);}cout << "这是一个析构函数" << endl;}protected:private:int a;char *p;};//给对象搭建一个舞台研究对象的行为voidobjPlay(){Test c1;c1.printP();cout << "分隔符" << endl;Test c2;c2.printP();}int main(){objPlay();cout << "hello world!" << endl;system("pause");return 0;}

匿名构造函数

#include <iostream>using namespace std;class Location { public:Location( int xx = 0 , int yy = 0 ) { X = xx ; Y = yy ; cout << "Constructor Object.\n" ; }//copy构造函数 完成对象的初始化Location(const Location & obj) //copy构造函数 {X = obj.X; Y = obj.Y;}~Location() { cout << X << "," << Y << " Object destroyed." << endl ; }int GetX () { return X ; }int GetY () { return Y ; }private : int X , Y ;} ;// g函数返回一个元素//你这么写代码,设计编译器的大牛们://我就给你返回一个新对象(没有名字 匿名对象)//由于函数的作用域因此这样能够实现,匿名函数//g函数 返回一个元素 //结论1 : 函数的返回值是一个元素 (复杂类型的), 返回的是一个新的匿名对象(所以会调用匿名对象类的copy构造函数)Location g(){Location A(1,2);return A; //因为A是一个局部变量,因此C++编译器是调用copy构造函数//返回的是一个匿名构造函数}//为了完整的展现对象的调用声明周期void objplay2(){g(); }//void objplay3(){//用匿名对象初始化m 此时c++编译器 直接把匿名对转成m;(扶正) 从匿名转成有名字了mLocation m = g(); printf("匿名对象,被扶正,不会析构掉\n");cout<<m.GetX()<<endl;;}void objplay4(){//用匿名对象 赋值给 m2后, 匿名对象被析构Location m2(1, 2);m2 = g();printf("因为用匿名对象=给m2, 匿名对象,被析构\n");cout<<m2.GetX()<<endl;;}int main(){objplay2();//objplay3();// objplay4();cout<<"hello..."<<endl;system("pause");return 0;}

匿名对象的去或留

#include <iostream>using namespace std;class Location { public:Location( int xx = 0 , int yy = 0 ) { X = xx ; Y = yy ; cout << "Constructor Object.\n" ; }//copy构造函数 完成对象的初始化Location(const Location & obj) //copy构造函数 {X = obj.X; Y = obj.Y;}~Location() { cout << X << "," << Y << " Object destroyed." << endl ; }int GetX () { return X ; }int GetY () { return Y ; }private : int X , Y ;} ;////结论2: 有关 匿名对象的去和留//如果用匿名对象 初始化 另外一个同类型的对象, 匿名对象 转成有名对象//如果用匿名对象 赋值给 另外一个同类型的对象, 匿名对象 被析构//这样写代码 C++编译器会认为你就是想返回一个新的对象的 没有名字所以是匿名对象Location g(){Location A(1,2);return A;}void objplay3(){//用匿名对象初始化m 此时C++编译器 直接把匿名对象转成m;(扶正)从匿名对象直接转换为有名字的mLocation m = g();//A被析构但是 m没有重建,因为采用的是将匿名对象转正为m,而不是从新生成一个mprintf("匿名对象转正,不会被析构掉\n");cout << m.GetX() << endl;}void objplay4(){Location m2(1,2);m2 = g();cout << "因为没有使用匿名对象 = 给m2,匿名对象,被析构" << endl;cout << m2.GetX() << endl;}int main(){//objplay3();cout <<endl <<endl << endl << endl << endl <<endl << endl;objplay4();cout<<"hello..."<<endl;system("pause");return 0;}

构造函数的的调用规则

当类中没有定义任意一个构造函数的时候C++编译器会提供一个默认的拷贝构造函数和无参数构造函数当类中定义了一个拷贝构造函数的时候,C++编译器不会提供无参数构造函数当类中定义了任意的非拷贝构造函数(即无参数构造函数或有参数构造函数),C++编译器不会提供无参数构造函数默认拷贝构造函数只对成员进行简单的赋值总结:在定义类时 只要你写了构造函数,你就得使用

使用C++默认的拷贝构造函数只是使用的是浅拷贝构造函数,当有指针变量的时候只会拷贝指针变量但是不会拷贝指针指向的数据

#define _CRT_SECURE_NO_WARNINGS#include <iostream>using namespace std;class Name{public:Name(const char *myp){int len = strlen(myp);p = (char *)malloc(len + 1);strcpy(p,myp); }~Name(){if(p != NULL){free(p); //屏蔽改行程序能够运行}}protected:private:char *p;int len;};void objplaymain(){Name obj1("agsuafujfa");Name obj2 = obj1;//执行C++默认得到拷贝构造函数,但是C++编译器只是一个浅拷贝,只是把指针变量的值拷贝过来没有把指针变量指向的数据拷贝过来//释放 obj2 的时候程序出现问题,说明**obj2**浅拷贝函数,直接使用的是obj1的指针变量而不是拷贝 obj1指针变量所指向的数值//这时再次调用obj1析构函数的时候就会出现问题}int main(){objplaymain();cout << "hello world!" << endl;system("pause");return 0;}

例如如图:

在必要的时候需要程序员自己写拷贝函数

使用深拷贝实现对象的赋值

解决办法就是自己编写拷贝函数

#define _CRT_SECURE_NO_WARNINGS#include <iostream>using namespace std;class Name{public:Name(const char *myp){m_len = strlen(myp);p = (char *)malloc(m_len + 1);strcpy(p,myp); }//Name obj2 = obj1Name(const Name& obj){m_len = obj.m_len;p = (char *)malloc(m_len + 1);strcpy(p,obj.p);}~Name(){if(p != NULL){free(p);}}protected:private:char *p;int m_len;};void objplaymain(){Name obj1("agsuafujfa");Name obj2= obj1; //执行C++默认得到拷贝构造函数,但是C++编译器只是一个浅拷贝,只是把指针变量的值拷贝过来没有把指针变量指向的数据拷贝过来}int main(){objplaymain();cout << "hello world!" << endl;system("pause");return 0;}

//等号操作符,也是默认使用的是浅拷贝,因此要是使用”= “操作符对对象进行赋值的时候需要使用操作符重载

#define _CRT_SECURE_NO_WARNINGS#include <iostream>using namespace std;class Name{public:Name(const char *myp){m_len = strlen(myp);p = (char *)malloc(m_len + 1);strcpy(p,myp); }//Name obj2 = obj1Name(const Name& obj){m_len = obj.m_len;p = (char *)malloc(m_len + 1);strcpy(p,obj.p);}~Name(){if(p != NULL){free(p);}}protected:private:char *p;int m_len;};void objplaymain(){Name obj1("agsuafujfa");//Name obj2= obj1; <==> obj2(obj1); //执行C++默认得到拷贝构造函数,但是C++编译器只是一个浅拷贝,只是把指针变量的值拷贝过来没有把指针变量指向的数据拷贝过来Name obj3("obj3");obj1 = obj3;//等号操作 C++提供的等号操作也是一个浅拷贝 解决办法是显式的从在"=" 操作符}int main(){objplaymain();cout << "hello world!" << endl;system("pause");return 0;}

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