关于对构造函数和拷贝构造函数的理解

    技术2022-05-13  6

    //关于对构造函数和拷贝构造函数的理解 //1、类和对象的关系 //首先我们要知道什么是类和对象,书上说的很详细,类就好比是定义一个变量的变量类型,而对象就是那个变量,比如定义i为int型:int i;相似的我们也可以 //把类定义对象写成这种情况,例如这:Point A;他们的关系就好比是定义车:车(类名,有各种车,但都叫车) 奔驰s300(这么多车的一种,当然名字可以随便取); //我们可以这样理解,先定义类-----再定义对象-----具体应用就是某个对象调用任意一个外部接口的成员函数 //2、构造函数的理解 //下面再说说构造函数,首先构造函数是一个名词,而不是一个动词,这就说明了他是一个有功能的函数,而不是指某个行为。由于编译器不能和编译int i=0;一样给类的对象也 //进行初始化(在声明对象的时候进行的数据成员设置就叫对象初始化,既然是声明,当然在主函数中咯),那么我们就利用定义一个成员函数来完成这种功能即:在对象被创建时利用特定的值构造对象,将对象初始化成为一个特定的状态,所以有这个作用的函数就叫做构造函数 //如何设置构造函数呢?就要知道构造函数的特点:1、要设置构造函数,首先构造函数的函数名应该和类名系统(应该是语法规定吧,这样就把这个函数当成构造函数看了) // 2、构造函数一般都是public(外部接口),被声明为共有函数。 //注:如果没有写构造函数,编译器会自动生成一个默认形式的构造函数--没有参数,也不做任何事(我认为这也许就说明了为什么设置构造函数的函数名应该和类名一致,因为这样才能保证一个 //类的构造函数只有一个!不会乱) //3、拷贝构造函数的理解 //对于拷贝构造函数我们也应该知道,他是一个名词,而不是动词,所以他是用来完成某些操作的项目,而不是为了目的去执行的操作。首先,拷贝构造函数是一种特殊的构造函数,具有一般构造 //造函数的性质即:函数名与类名系统,一般放在外部接口。由于他的作用是将一个已经存在的对象初始化同类的新对象,所以他就需要一个形参确定是用什么对象(设为A)和去初始化什么对象 //(就是这个新对象的名字,设为B),具体格式问题在后面会说明。 //注意:和构造函数一样,如果没有定义,编译器会自动生成一个默认的拷贝构造函数,这个默认的拷贝构造函数的功能就是,把初始值对象的每个数据成员的值都复制到新建立的对象中。 //4、下面就具体的问题谈谈格式的问题 #include <iostream> using namespace std; class Point //定义Point类 { public: //设置外部接口 //5、接口处成员函数(包括构造函数和拷贝构造函数)的声明(我个人认为这个词比较恰当,当然这里也可以直接进行把函数进行定义) //这里就像是一个函数的定义,由于这里的Point是系统默认的不用加类型(注:这里虽然在vs2005中把下面的Point前加class不会报错但是不能加,其实这是历史原因:在sturct中struct data d1; //老的C语言只能这么写,C++为了保持兼容也可以编译通过这个语句 data d2; C++可以这么写,但老的C语言不支持 所以之后引入class之后,也保持同样的惯例 代码中写class Point就等价 //于写Point,没有区别) //括号里面的是参数的定义,构造函数和拷贝构造函数的格式 :类名(前面说了原因) (参数,如果是构造函数就写成想设定的参数,如果是拷贝构造函数就设定为Point &p //这是因为,拷贝构造函数是把一个对象的值拷贝到另一个对象,那么参数也就应该是一个对象,所以要用Point定义类型+空格+&+一个随便的变量代表参数) //这里我认为有必要说说为什么要加上一个&,自习看看拷贝构造函数的实现过程,是没有return的!!!为啥?因为这里有2个值需要返回呗!那么咋办?用我们前面学习的引用调用 //不就完事了?哈哈,这就是为什么要加上一个&的原因。但是有人又会问,为什么构造函数就不加呢?原因很简单,下面fun2函数对构造函数的调用返回的是他的一个对象,所以不需要。 Point(int xx=0,int yy=0){X=xx;Y=yy;}; //构造函数,注,这里是内联函数,把{X=xx;Y=yy;}写在外面构造也可以,但是xx和yy就不能被赋值了,具体见下面注1 Point(Point &p); //拷贝构造函数 int GetX(){return X;} //别的成员函数 int GetY(){return Y;} private: int X,Y; //设置私有接口 }; //注1: //里面写成Point(int xx,int yy); //Point::Point(int xx=0,int yy=0) //{ // X=xx; // Y=yy; //} Point::Point(Point &p) //拷贝构造函数的实现,类名::成员函数名(参数类型 参数名) { X=p.X; Y=p.Y; } //下面是调用拷贝构造函数的三种情况 //一、形参为Point类对象的函数 //这里是定义一个形参为Point类的对象的函数,并完成某些功能,注:由于p是一个形参,形参就应该有类型,所以一定要写上Point void fun1(Point p)//这里不加&是因为返回值是一个 { cout<<p.GetX()<<endl; } //二、返回值为Point类对象的函数 Point fun2() { Point A(1,2); return A; } int main() //主函数 { Point A(4,5); //这里是定义A为Point类的一个对象,又由于定义了构造函数,可以进行初始化,而不用和再定义一个成员函数来传递,比如书上的Clock中的GetClock就是传递用的 //这里就利用了构造函数Point(int xx=0,int yy=0)定义的对象A的实参带入 Point B(A); //三、当类的一个对象去初始化该类的一个对象时,拷贝构造函数被调用 //这里就调用了拷贝构造函数Point(Point &p),这里先是定义B为对象,再把一个已经有的对象A当作实参传递进去,看见为了达到这种目的,拷贝构造函数的形参应该为 //类的一个对象,带入的对象应该是已知的 cout<<B.GetX()<<endl;//第三种情况的输出,这里比如对象B的GetX()就用B.GetX(),这点和结构体中的相似,"."就好比是“的”的意思。 //下面是要说明当函数的返回值为类的对象时,拷贝构造函数会被调用 fun1(B);//fun1函数的调用 B=fun2();//fun2函数的调用 cout<<B.GetX()<<endl; }


    最新回复(0)