C++类构造函数初始化列表
- 格式:pdf
- 大小:419.77 KB
- 文档页数:2


C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执⾏顺序和执⾏内容⼀、本⽂⽬的与说明1. 本⽂⽬的:理清在各种继承时,构造函数、复制构造函数、赋值操作符、析构函数的执⾏顺序和执⾏内容。
2. 说明:虽然复制构造函数属于构造函数的⼀种,有共同的地⽅,但是也具有⼀定的特殊性,所以在总结它的性质时将它单独列出来了。
3. 单继承、多继承、虚继承,既然都属于继承,那么虽然有⼀定的区别,但还是相同点⽐较多。
如果放在⼀块讲,但为了将内容制作成递进的,就分开了,对相同点进⾏重复,(⼤量的复制粘贴哈),但在不同点进⾏了标注。
注意:三块内容是逐步递进的如果你懂虚函数,那么单继承和多继承那块你就可以不看;如果你懂多继承,那单继承你就不要看了,⾄于虚继承就等你懂虚继承再回来看吧;如果你只懂单继承,那你就只看单继承就好。
⼆、基本知识1. 对于⼀个空类,例如:class EmptyClass{};虽然你没有声明任何函数,但是编译器会⾃动为你提供上⾯这四个⽅法。
class EmptyClass {public:EmptyClass(); // 默认构造函数EmptyClass(const EmptyClass &rhs); // 复制构造函数~EmptyClass(); // 析构函数EmptyClass& operator=(const EmptyClass &rhs); // 赋值运算符}对于这四个⽅法的任何⼀个,你的类如果没有声明,那么编译器就会⾃动为你对应的提供⼀个默认的(注意合成默认构造函数是⽤于没有编写构造函数编译器才会合成默认构造函数,其中复制构造函数也是构造函数)。
(在《C++ primer》中,这个编译器⾃动提供的版本叫做“合成的***”,例如合成的复制构造函数)当然如果你显式声明了,编译器就不会再提供相应的⽅法。
2. 合成的默认构造函数执⾏内容:如果有⽗类,就先调⽤⽗类的默认构造函数。
c++中冒号(:)的⽤法(1)表⽰机构内位域的定义(即该变量占⼏个bit空间)typedef struct _XXX{unsigned char a:4;unsigned char c;} ; XXX(2)构造函数后⾯的冒号起分割作⽤,是类给成员变量赋值的⽅法,初始化列表,更适⽤于成员变量的常量const型。
struct _XXX{_XXX() : y(0xc0) {}};(3) public:和private:后⾯的冒号,表⽰后⾯定义的所有成员都是公有或私有的,直到下⼀个"public:”或"private:”出现为⽌。
"private:"为默认处理。
(4)类名冒号后⾯的是⽤来定义类的继承。
class 派⽣类名 : 继承⽅式基类名{派⽣类的成员};继承⽅式:public、private和protected,默认处理是public。
2、类构造函数(Constructor)的初始化列表先说下什么叫构造函数吧(是不是啰嗦了?C++的⼈应该都知道了吧,还是以防万⼀⼀下)。
所谓构造函数,就是与类同名的函数,它与普通函数的区别在于,它没有返回类型。
在构造函数后⾯紧跟着冒号加初始化列表,各初始化变量之间以逗号(,)隔开。
下⾯举个例⼦。
class myClass{public :myClass();// 构造函数,⽆返回类型,可以有参数列表,这⾥省去~myClass();// 析构函数int a;const int b;}myClass::myClass():a(1),b(1)// 初始化列表{}上⾯的例⼦展⽰了冒号的这个⽤法,下⾯对这个⽤法进⾏⼏点说明:1)初始化列表的作⽤相当于在构造函数内进⾏相应成员变量的赋值,但两者是有差别的。
在初始化列表中是对变量进⾏初始化,⽽在构造函数内是进⾏赋值操作。
两都的差别在对于像const类型数据的操作上表现得尤为明显。
我们知道,const类型的变量必须在定义时进⾏初始化,⽽不能对const型的变量进⾏赋值,因此const类型的成员变量只能(⽽且必须)在初始化列表中进⾏初始化,即下⾯的代码将会出错:myClass::myClass(){a = 1;// 没错,效果相当于在初始化列表中进⾏初始化b = 1;// 出错,const变量不能进⾏赋值操作;}2)初始化的顺序与成员变量声名的顺序相同。
initlist函数Initlist函数是一种用于初始化线性表的函数,也称为静态初始化函数。
它是用于在C/C++程序中创建线性表的必需步骤,可以将元素的存储空间快速分配到存储器中,加快程序的运行效率。
Initlist函数的定义格式为:initlist(type name[], int n, type value);其中type可以是char、int、float、double等数据类型,name[]为线性表的类型,n为线性表的元数,value为批量赋值的值。
Initlist函数的实现方式:传统实现方式:在使用initlist函数时,需要编写for循环,循环n次,将索引为i的元素赋值为value。
例:int arr[5];initlist (arr,5,0); //将arr[5]全部赋值为0for(int i=0;i<5;i++){arr[i] = 0;}改进的实现方式:使用模板实现Initlist函数,可以更加简化对线性表的初始化过程,模板实现方式如下:void initlist( type name[], unsigned int n, type value ) {while ( n-- > 0 )*name++ = value;}根据上述实现方式,使用initlist函数时无需编写for循环,只需传入线性表的元数,以及要赋值的值即可,大大减少了程序的复杂程度。
Initlist函数也可以用于二维数组的初始化,例如:int arr[3][3];initlist(arr,9,0); //将arr[3][3]矩阵内所有元素全部赋值为0initlist(arr[0],3,1); //将arr[0][3]中所有元素赋值为1 至此,使用initlist函数可以快速简单的初始化线性表或二维数组,提高程序运行的效率。
Initlist函数在实际使用中也有一些注意事项:1. Initlist函数的参数 n大小必须与线性表的元数一致,否则会出现越界访问的异常,导致程序出错。