新引入了类这个概念,你别说突然之间各种概念就多起来麻烦起来了。今天来说说构造函数和折构函数。
一、构造函数和拷贝构造函数
1. 构造函数
简单的说,构造函数就是给类成员初始化的函数。那怎么使用呢?我们直接上代码:
1 //构造函数 2 #include<iostream> 3 using namespace std; 4 class Date 5 { 6 public: 7 int output(); 8 Date(int,int,int); 9 Date(); 10 private: 11 int year,month,day; 12 }; 13 14 Date::Date(int x, int y, int z):day(z) 15 { 16 year=x; 17 month=y; 18 } 19 Date::Date():year(1),month(1) 20 { 21 day=1; 22 } 23 int Date::output() 24 { 25 cout<<"输出:"<<year<<"年"<<month<<"月"<<day<<"日"<<endl; 26 } 27 int main() 28 { 29 Date d1(1997,4,24); 30 Date d2; 31 Date d3; 32 d3=Date(2015,12,13); 33 d1.output(); 34 d2.output(); 35 d3.output(); 36 return 0; 37 }
看代码说话,重点易错内容用圆圈序号标出:
第8、9行的Date(int, int, int)和Date(int)这两个函数就是构造函数,可以发现它与类类型名相同,①构造函数名只能和类类型名相同,且声明时都不能标函数类型(void也不能标)。
看到第14到23行,这里是函数的定义,写明了函数要做什么事情:主要就是初始化赋值。②定义时也不能标注函数类型,同时也不可以有返回值。③构造函数可以有参数也可以没有参数。这个小程序这里使用了函数重载,④构造函数也可以使用函数重载,调用时根据调用的方式确定到底是哪个。在定义构造函数时可以看出,⑤给变量赋值有两种方式,即在参数表圆括号后的“:”后面写变量(值),或是一般的在函数体中间写,运行的顺序是初始化区域→函数体。
接下来说说怎么调用构造函数。构造函数不需要手动调用,看到第29至30行,⑥构造函数会在定义类变量的时候自动调用,调用时根据调用时的参数表格式确定是函数重载重的哪个,特别注意的是定义变量要调用没有参数的构造函数时不要括号,即30行不是“Date d2()”而是“Date d2”。另外嘞,还可以⑦给已经定义声明过的变量重新使用构造函数赋值,方法同第32行,注意等号右边是“Date(......)”,即类型名(......)。
每一个类至少需要一个构造函数,如果用户没有编写构造函数,系统会自动创建一个,只会它不会做任何事情,输出出来就是乱码。所以需要用户自己写咯,⑧一旦有用户自己写的构造函数,调用时就不会调用自己创建的了,所以调用时的参数错了直接就提示:没有定义这个函数了。
2. 拷贝构造函数
拷贝构造函数用于使用一个已经存在的对象来初始化另一个同类型的对象。它具有唯一参数。
1 //构造拷贝函数:例1. 2 #include<iostream> 3 using namespace std; 4 class Date 5 { 6 public: 7 int output(); 8 Date(int, int, int); //构造函数 9 Date(Date &); //拷贝构造函数 10 private: 11 int year,month,day; 12 }; 13 Date::Date(int x,int y,int z) 14 { 15 year=x; 16 month=y; 17 day=z; 18 } 19 Date::Date(Date &d) //拷贝构造函数 20 { 21 year=d.year+1; //拷贝的year值+1 22 month=d.month; 23 day=d.day; 24 } 25 int Date::output() 26 { 27 cout<<"输出:"<<year<<"年"<<month<<"月"<<day<<"日"<<endl; 28 } 29 int main() 30 { 31 Date d1(2016,2,14); 32 Date d2(d1); 33 d1.output(); 34 d2.output(); 35 }
//结果:
输出:2016年2月14日
输出:2017年2月14日
可以看到拷贝构造函数初始化d2时是跟d1的初始化有关联的。拷贝构造函数在一下三种情况中会被调用:
①一个对象通过另一个对象初始化,如上面的例1.
②一个对象以值传递的方式使用
//例2.
void func(Date d) { date.output(); } int main() { Date d1(2015,6,7); func(d1); }
③一个对象以值传递的方式从函数返回
//例3.
Date fun2() { Date d1(2015,6,8); return d1; } int main() { fun2().output(); }
例2和例3中并没有出现定义拷贝构造函数,是因为用户没有自定义拷贝构造函数,系统会自动弄一个默认的拷贝构造函数,用于传值的过程。
但是系统默认的拷贝构造函数是浅拷贝,即拷贝的本体和复制体指向同一个空间,
原文:http://www.cnblogs.com/HappyCtest/p/5189383.html