默认成员函数:
默认成员函数分为6种,他们都是如果我们不写,编译器会自动生成的函数,如果写了,编译器就不会生成了
前面四个是非常重要的,后面两个用得不多
构造函数:
我们在平常写一个类得时候,就怕我们没有给他进行初始化,我们再去访问就是随机值了,怎么解决这种不确定性呢,这个时候我们得默认构造函数就出来了
构造函数的特性:
构造函数是一种特殊的成员函数,构造函数的主要任务不是去创建对象,而是去初始化对象。
- 函数名与类名相同。
- 没有返回值。
- 对象实例化的时候会自动调用构造函数
- 可以重载
这些是构造函数的特性,来看看他写出来是什么样吧:
class stu { public: stu() { _a = 10; _c = 'A'; _b = 20; } stu(int a, char c, int b) { _a = a; _c = c; _b = b; } void test1() { cout << _a << "-" << _c << "-" << _b << endl; } private: int _a; char _c; int _b; };
这里就是一个重载,构造函数的参数也是可以加缺省值的,建议呢是全部都加上缺省值,这样也可以防止传参的时候写错而出些错误(注意给缺省值的顺序是从右往左给的)
如果你想调用一个不用传参的构造函数,定义的时候应该是这样的:
class stu { public: stu() { _a = 10; _c = 'A'; _b = 20; } stu(int a, char c, int b) { _a = a; _c = c; _b = b; } void test1() { cout << _a << "-" << _c << "-" << _b << endl; } private: int _a; char _c; int _b; }; int main() { stu s1; stu s3(4, 'C', 40); }
大家看见没有,这里是不需要加括号的,加上括号反而会出错,编译器会认为你定义那里并没有定义出一个对象,无法区分是一个函数的声明还是对象的定义;传参的时候也是在对象的后面直接传参的。
还有一个小小的细节:我们的全缺省的构造函数和自己写的无参的构造函数不要同时存在,虽说他们在语法上,不使用这个类,是可以编译通过的,但是一旦我们使用,用这个类定义一个不传参的对象,这就会报错了,因为两个构造函数都是可以不用传参可以直接调用的,编译器这个时候就不知道用哪个了,然后就报错了
所以我平常写的时候,如果有需要,都是定义为全缺省的,既方便也不容易出错
内置、自定义类型?
我们要学习默认构造函数,就要知道内置类型和自定义类型,内置类型就是我们平常经常用的那些类型,自定义类型顾名思义就是我们自己定义的类型
我们编译器默认生成的构造函数对内置类型不做处理,对于自定义类型会去调用它的构造函数:
class date { public: date() { _a=100; } private: int _a; }; class stu { public: void print() { cout << _a << "-" << _c << "-" << _b << endl; } private: int _a; char _c; int _b; date a1; }; int main() { stu s3 }
对于初始化是区分化处理的,我的内置类型得不到初始化除非自己显示得去写,大家有没有觉得挺奇怪的呢?所以有了一个这样的总结:
如果一个类中的成员全是自定义类型,我们就用自己默认生成的就够了,有内置成员、或者要显示传参,就要自己写了。
对于这种处理方式呢,后面在c++11里面给了一个解决办法就是这样:
class date { public: date() { _a=100; } private: int _a; }; class stu { public: void print() { cout << _a << "-" << _c << "-" << _b << endl; } private: int _a = 10; char _c = 'A'; int _b = 20; date a1; }; int main() { stu s3 }
这里给的不是一个赋值,这里依旧只是声明,我们给的值是一个缺省值,是给我们构造函数的初始化列表使用的,如果我们我自己写了构造函数,并给内置类型赋值了,就不会用这些给的缺省值了,大家学到后面初始化列表就知道怎么回事了
构造函数的小细节:
一:
我们自己写的构造函数对于自定义类型也是会处理的:
二:
注意:无参的构造函数和全缺省的构造函数也是可以叫做默认构造函数的(他们和编译器默认生成的都是不需要传参的),但是默认构造函数只能有一个且必须有一个(也可以是半缺省),六大成员函数包括编译器自动生成的默认构造,我们上面说过无参的和全缺省的不能写在一起报错就是这样的:
三:
没有默认构造可用的情况就是这样的:
class stu { public: stu(int a ,char c='A',int b=20) { _a = a; _c = c; _b = b; } void print() { cout << _a << "-" << _c << "-" << _b << endl; } private: int _a; char _c; int _b; }; int main() { stu s1; }
这里就是编译器因为你自己写了,就没有生成默认的,但是你自己写的,你也没用,就报错了!!!