大家好
欢迎回来继续学习
C++语言程序设计
这一节我们来学习构造函数
现在我们考虑一个问题
当我们定义对象的时候
怎么样对对象进行初始化
我们知道当我们定义一个
基本类型的变量的时候
是可以同时给它指定初始值的
但是定义对象的时候
我们能够直接给出初始值
就达到初始化的效果吗
想象一下
应该不是那么简单的事
因为一个类
是我们自己定义的类型
对这个自定义的类型
按照什么规则进行初始化
编译器不会自动知道的
这件事一定得我们程序员
写程序来规定
为此C++语法中
提供了一种特殊的机制
就是构造函数
我们可以在类体中
写一种特殊的函数
叫做构造函数
在构造函数中
我们就可以描述
如何对类的对象进行初始化
把初始化的规则 算法
写在构造函数中
接下来我们就来看
构造函数怎么写
现在我们考虑
如果希望在构造一个
比如说钟表类的对象
Clock类对象的时候
将初始的时间设置为0：0：0
那么这件事怎么做呢
这件事
我们就可以通过构造函数来设置
构造函数的作用就是
在对象被创建的时候
使用特定的值
把对象初始化到一个
特定的初始状态
那么语法上的规定呢
构造函数
它的函数名必须与类名相同
构造函数不能定义返回值类型
也不能在函数体中有return语句
与其他的函数一样
构造函数也可以有形式参数
当然没有形式参数
也是可以的
构造函数也可以是内联函数
可以重载
还可以带有默认的参数值
这些都可以
那么大家可能会有一个疑问
构造函数在什么时候调用呢
我们需不需要在程序中
写代码显示的调用构造函数呢
不用
构造函数是在我们
构造新对象
定义新对象的时候
自动被调用的
比如说我们在这里构造一个
Clock类的对象 myClock
希望将这个时钟对象
它的初始状态设置成0：0：0
那这样
我们就把初始值
放在对象名后面的括号里面
如果我们在这个Clock类里面
定义了构造函数
并且这个构造函数
可以接收三个int类型的数据
作为实参
那么在这个时刻构造函数
就会被调用
如果在Clock类里面
没有定义构造函数
我们像这样写了
一厢情愿的初始化
那编译器就会报错
说找不到这种形式的构造函数
好 如果说
我们在定义类的时候
没有写构造函数
那又会怎么样呢
我们定义构造函数的时候
可以有参数表
也可以让参数表空着
也就是说构造函数可以有参数
也可以没参数
即使一个构造函数
它有参数
我们也可以给所有的参数
都指定默认值
也就是说
实际在调用构造函数的时候
有可能你根本就不需要
给初始化参数
那么如果一个构造函数
它在被调用的时候
不需要实参
我们就称这个构造函数
是一个默认的构造函数
default constructor
比如说
我们看这里列出来两个构造函数
一个是没有形参的
大家看参数表是空的
另一个有形参
但是全部的形参
都指定了默认值
也就是说这两个函数
你调用它的时候
都可以不给参数
所以说
这两个函数不能同时
出现在一个类里面
它不是合法的函数重载形式
因为你如果不给参数
去初始化一个新对象的话
编译器就不知道
该调用这两个函数中的哪一个了
如果我们在定义一个类的时候
完全就没有定义构造函数
那么这个类的对象
该如何初始化呢
这个时候构造新对象的时候
到底会不会去调用构造函数呢
这一点我们应该知道
构造一个新对象的时候
调用构造函数是必须的
不可能说构造一个新对象
但是不调用任何构造函数
那为什么我们很多时候
写简单程序的时候
又可以在类体里面
不声明构造函数呢
如果说我们定义一个类的时候
不声明任何构造函数
那么编译器在编译的时候
就会为我们自动生成一个
构造函数
这个生成的构造函数呢
是一个隐含的默认的构造函数
这个隐含的默认的构造函数
它的参数表是空的
所以我们不能通过
这个默认构造函数
为数据成员设置初始值
那如果这个时候
类内部定义了成员的初始值
初始化就会使用定义的初始值
如果没有定义的初始值
那么就使用默认的方式初始化
什么是默认的方式初始化呢
如果你定义的数据成员
都是基本类型的成员
那么初始化的值是不确定的
我们一开始讲
简单的变量定义的时候讲过
大家还记得吧
一个变量你如果定义它
但是不初始化
它里面可能放的就是垃圾数据
如果你定义的类的数据成员
不是基本类型的成员
而是其他的另外一个类的对象
那么这个就是我们后面要说的
这个类组合的情况
在这种情况下
对象成员
它的默认初始化方式是什么呢
它的默认初始化方式
由它所属的类来决定
下面我们通过一个例子
来看看如何在程序中
定义和使用构造函数
如果我们在程序中
自己定义了构造函数
在默认情况下
编译器就不再隐含生成
默认的构造函数了
如果说我们自己定义了构造函数
但是依然希望编译器
还为我们生成
隐含的默认构造函数
这也是可以的
这个时候我们就可以使用
这个default这个关键字
那我们来看这个例子
在Clock类里面
大家看
我们自己定义了一个构造函数
带三个参数
那么这个时候呢
编译器默认情况下
就不给我们生成
这个默认的构造函数了
如果我们需要的话
我们需要自己去写一个
无参数的构造函数
那现在C++11给了我们一种
新的办法
就是我们用default来说明
我们依然需要编译器
隐含生成的默认构造函数
这就指示编译器
依然为我们提供构造函数