当前课程知识点:C++语言程序设计基础 > 第4章 类与对象 > 构造函数 > 构造函数基本概念
大家好
欢迎回来继续学习
C++语言程序设计
这一节我们来学习构造函数
现在我们考虑一个问题
当我们定义对象的时候
怎么样对对象进行初始化
我们知道当我们定义一个
基本类型的变量的时候
是可以同时给它指定初始值的
但是定义对象的时候
我们能够直接给出初始值
就达到初始化的效果吗
想象一下
应该不是那么简单的事
因为一个类
是我们自己定义的类型
对这个自定义的类型
按照什么规则进行初始化
编译器不会自动知道的
这件事一定得我们程序员
写程序来规定
为此C++语法中
提供了一种特殊的机制
就是构造函数
我们可以在类体中
写一种特殊的函数
叫做构造函数
在构造函数中
我们就可以描述
如何对类的对象进行初始化
把初始化的规则 算法
写在构造函数中
接下来我们就来看
构造函数怎么写
现在我们考虑
如果希望在构造一个
比如说钟表类的对象
Clock类对象的时候
将初始的时间设置为0:0:0
那么这件事怎么做呢
这件事
我们就可以通过构造函数来设置
构造函数的作用就是
在对象被创建的时候
使用特定的值
把对象初始化到一个
特定的初始状态
那么语法上的规定呢
构造函数
它的函数名必须与类名相同
构造函数不能定义返回值类型
也不能在函数体中有return语句
与其他的函数一样
构造函数也可以有形式参数
当然没有形式参数
也是可以的
构造函数也可以是内联函数
可以重载
还可以带有默认的参数值
这些都可以
那么大家可能会有一个疑问
构造函数在什么时候调用呢
我们需不需要在程序中
写代码显示的调用构造函数呢
不用
构造函数是在我们
构造新对象
定义新对象的时候
自动被调用的
比如说我们在这里构造一个
Clock类的对象 myClock
希望将这个时钟对象
它的初始状态设置成0:0:0
那这样
我们就把初始值
放在对象名后面的括号里面
如果我们在这个Clock类里面
定义了构造函数
并且这个构造函数
可以接收三个int类型的数据
作为实参
那么在这个时刻构造函数
就会被调用
如果在Clock类里面
没有定义构造函数
我们像这样写了
一厢情愿的初始化
那编译器就会报错
说找不到这种形式的构造函数
好 如果说
我们在定义类的时候
没有写构造函数
那又会怎么样呢
我们定义构造函数的时候
可以有参数表
也可以让参数表空着
也就是说构造函数可以有参数
也可以没参数
即使一个构造函数
它有参数
我们也可以给所有的参数
都指定默认值
也就是说
实际在调用构造函数的时候
有可能你根本就不需要
给初始化参数
那么如果一个构造函数
它在被调用的时候
不需要实参
我们就称这个构造函数
是一个默认的构造函数
default constructor
比如说
我们看这里列出来两个构造函数
一个是没有形参的
大家看参数表是空的
另一个有形参
但是全部的形参
都指定了默认值
也就是说这两个函数
你调用它的时候
都可以不给参数
所以说
这两个函数不能同时
出现在一个类里面
它不是合法的函数重载形式
因为你如果不给参数
去初始化一个新对象的话
编译器就不知道
该调用这两个函数中的哪一个了
如果我们在定义一个类的时候
完全就没有定义构造函数
那么这个类的对象
该如何初始化呢
这个时候构造新对象的时候
到底会不会去调用构造函数呢
这一点我们应该知道
构造一个新对象的时候
调用构造函数是必须的
不可能说构造一个新对象
但是不调用任何构造函数
那为什么我们很多时候
写简单程序的时候
又可以在类体里面
不声明构造函数呢
如果说我们定义一个类的时候
不声明任何构造函数
那么编译器在编译的时候
就会为我们自动生成一个
构造函数
这个生成的构造函数呢
是一个隐含的默认的构造函数
这个隐含的默认的构造函数
它的参数表是空的
所以我们不能通过
这个默认构造函数
为数据成员设置初始值
那如果这个时候
类内部定义了成员的初始值
初始化就会使用定义的初始值
如果没有定义的初始值
那么就使用默认的方式初始化
什么是默认的方式初始化呢
如果你定义的数据成员
都是基本类型的成员
那么初始化的值是不确定的
我们一开始讲
简单的变量定义的时候讲过
大家还记得吧
一个变量你如果定义它
但是不初始化
它里面可能放的就是垃圾数据
如果你定义的类的数据成员
不是基本类型的成员
而是其他的另外一个类的对象
那么这个就是我们后面要说的
这个类组合的情况
在这种情况下
对象成员
它的默认初始化方式是什么呢
它的默认初始化方式
由它所属的类来决定
下面我们通过一个例子
来看看如何在程序中
定义和使用构造函数
如果我们在程序中
自己定义了构造函数
在默认情况下
编译器就不再隐含生成
默认的构造函数了
如果说我们自己定义了构造函数
但是依然希望编译器
还为我们生成
隐含的默认构造函数
这也是可以的
这个时候我们就可以使用
这个default这个关键字
那我们来看这个例子
在Clock类里面
大家看
我们自己定义了一个构造函数
带三个参数
那么这个时候呢
编译器默认情况下
就不给我们生成
这个默认的构造函数了
如果我们需要的话
我们需要自己去写一个
无参数的构造函数
那现在C++11给了我们一种
新的办法
就是我们用default来说明
我们依然需要编译器
隐含生成的默认构造函数
这就指示编译器
依然为我们提供构造函数
-导学
--第1章导学
-计算机系统简介
--计算机系统简介
--计算机系统简介 测试题
-计算机语言和程序设计方法的发展
--计算机语言和程序设计方法的发展 测试题
-面向对象的基本概念
--面向对象的基本概念 测试题
-程序的开发过程
--程序的开发过程
--程序的开发过程 测试题
-信息的表示和储存
--计算机的数字系统
--数据的编码表示
--信息的表示和储存 测试题
-实验指导
-导学
--第二章导学
-C++语言概述
--C++语言概述 测试题
-基本数据类型、常量、变量
--程序举例
--基本数据类型、常量、变量 测试题
-运算与表达式
--运算与表达式 测试题
-实验二:简单程序设计(上)
-数据的输入和输出
--数据的输入和输出
--数据的输入和输出 测试题
-选择结构
--if语句
--switch语句
--选择结构 测试题
-循环结构
--for语句
--循环结构 测试题
-自定义类型
--自定义类型
--自定义类型
-第2章小结
--第二章小结
-实验二:C++简单程序设计(下)
-导学
--导学
-函数定义
--函数定义
--函数定义 测试题
-函数调用
--例3-2
--例3-3
--例3-4
--例3-5
--例3-6
--函数调用 测试题
-嵌套与递归
--例3-9
--例3-10
--嵌套与递归 测试题
-函数的参数传递
--函数的参数传递
--函数的参数传递 测试题
-引用类型
--引用类型 测试题
-含有可变参数的函数
--含有可变参数的函数 测试题
-内联函数
--内联函数 测试题
-constexpr函数
--CONSTEXPR函数课后习题
-带默认参数值的函数
--带默认参数值的函数 测试题
-函数重载
--函数重载 测试题
-C++系统函数
--C++系统函数习题
-第3章小结
--第三章小结
-实验三(上)函数的应用
-实验三(下)函数的应用
-导学
--导学
-面向对象程序的基本特点
--面向对象程序的基本特点 测试题
-类和对象
--类和对象的定义
--类和对象 测试题
-构造函数
--构造函数基本概念
--委托构造函数
--复制构造函数
--构造函数 测试题
-析构函数
--析构函数
--析构函数 测试题
-类的组合
--类的组合
--类的组合程序举例
--前向引用声明
--类的组合 测试题
-UML简介
--UML简介
--UML简介课后习题
-结构体与联合体
--结构体与联合体 测试题
-枚举类
--枚举类
--枚举类 测试题
-第4章小结
--第四章小结
-实验四(上)
--实验四(上)
-实验四(下)
--实验四(下)
-导学
--导学
-标识符的作用域与可见性
--标识符的作用域与可见性 测试题
-对象的生存期
--对象的生存期
--对象的生存期 测试题
-类的静态成员
--类的静态成员 测试题
-类的友元
--类的友元 测试题
-共享数据的保护
--共享数据的保护 测试题
-多文件结构和预编译命令
--多文件结构和预编译命令 测试题
-第5章小结
--小结
-实验五
--实验五
-导学
--导学
-数组的定义与初始化
--数组的定义与使用
--一维数组应用举例
--数组的定义与初始化 测试题
-数组作为函数的参数
--数组作为函数的参数 测试题
-对象数组
--对象数组
--对象数组 测试题
-基于范围的for循环
-指针的定义和运算
--指针的定义和运算 测试题
-综合实例
--综合实例
-实验六(上)
--实验六上
-指针与数组
--指针数组
--指针与数组 测试题
-指针与函数
--指针类型的函数
--指向函数的指针
--指针与函数 测试题
-对象指针
--对象指针
--对象指针 测试题
-动态内存分配
--动态内存分配 测试题
-智能指针
--智能指针
-vector对象
--vector对象
--vector对象 测试题
-对象复制与移动
--移动构造
--对象复制与移动 测试题
-字符串
--C风格字符串
--string类
--字符串 测试题
-第6章小结
--第六章小结
-综合实例
--综合实例
-实验六(下)
--实验六(下)