this指针:
在谈构造函数之前,有这样两个问题:
1.this指针存在哪里?
2.this指针可以为空吗?
问题1:this 指针是形参,形参和函数中局部变量都是存在函数栈帧里面的,所以this指针可以认为是存在栈的;vs为了提高效率,this指针是通过寄存器ecx传递的。
问题2:
成员函数的地址不在对象中存储,存在公共代码段;这里调用成员函数,不会去访问p指向的空间,也就不存在空指针解引用了,这里会把p传递给隐含的this指针,但是Show函数也没有解引用this指针。
底层并没有对空指针引用;
此时的结果为程序崩溃;此时Print函数要解引用访问成员变量;空指针的解用;
构造函数:
在c语言中,我们定义一个栈的结构体,会专门写一个函数去初始化它,但是有时候我们也经常忘记去写这个初始化函数,在c++中就得到了解决,它做到了对象定义出来就可以初始化:
构造函数:它的主要任务是初始化对象,而不是开空间去构造对象;
特征:1.类名与函数名相同。
2.无返回值。
3.对象实例化时编译器自动调用对
应的构造函数。
4.构造函数可以重载。
重载的意思是提供多种初始化对象的方式;
5.如果类中没有显示定义构造函数,则C++编译器会自动生成一个默认无参的构造函数,一旦用户显示定义编译器将不再生成。
没有写构造函数时,系统会自动生成;但是我们发现系统生成的默认构造函数没有起什么作用,这也是早期C++设计的一个缺陷,但是也并不是没有用
c++将类型分为内置类型和自定义类型,内置类型:int ,char,double,指针…,自定义类型:struct、class
我们不写构造函数,编译器默认说我生成构造函数,做了一个偏心处理:
1.内置类型不会初始化
2.自定义类型他会调用他的无参构造函数初始化
c++11打了个补丁:
tip:初始化只有在开了空间之后才可以初始化;
6.无参的构造函数和全缺省的构造函数都成为默认构造函数,并且默认构造函数只能有一个。注意:无参构造函数,全缺省构造函数,我们没有写编译器默认生成的构造函数,都可以认为是默认构造函数。
总结:不传参数就可以调的那个。
初始化列表:
观察这段代码会发现:怎么打印了三句话。
通过调试,我们可以看出,刚进入构造函数B的时候,会立马对成员变量进行初始化;
这里可以看出_aa,代价很大
接下来,就要引出我们的主题,初始化列表:
(上面我们介绍的初始化是构造函数体内部初始化)
自定义类型成员,改用初始化列表初始化,可以提高效率:
可以看出此时只调用了一次构造函数:
初始化列表中自定义类型可以调用有参的构造函数,而函数体内初始化,对成员变量是自定义类型的时候,只会掉用无参的构造函数;
C++中比较推荐用初始化列表;因为你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
就算你不写也会有初始化列表:
所以尽量使用使用初始化列表;
有些变量必须用初始化列表初始化:
const变量必须在定义的时候初始化,成员变量是在初始化列表的时候定义的,const成员变量已经定义了,就不能赋值了,所以const成员变量不能在函数体初始化。同样的道理引用也要在初始化列表进行初始化。
总结:
总结:
1.尽量使用初始化列表初始化,因为就算你不显示用初始化列表,成员也会先用初始化列表初始化一遍。
2.有些成员是必须在初始化列表初始化。引用,const,没有默认成员函的成员
3.初始化列表和函数体内初始化,可以混着用,互相配合
接下来看一道题:
这里有个知识点:成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中出现的先后次序无关;