1. 构造函数的介绍
-
功能:专门用于对象的初始化工作,在类的对象创建时定义初始状态
-
特点
-
- 构造函数的名字和类名是相同的
-
- 构造函数是没有返回值类型的,也不能写 void 。可以有形参(也可以重载)
-
- 在创建对象的时候,会自动调用。而且是一定会调用,但是只会调用一次,不能通过已有对象
手动调用构造函数。
- 在创建对象的时候,会自动调用。而且是一定会调用,但是只会调用一次,不能通过已有对象
-
- 如果一个类中没有显示声明的构造函数,那么编译器会自动生成一个无参构造函数,自动生成
的构造函数,函数体为空且没有参数。
- 如果一个类中没有显示声明的构造函数,那么编译器会自动生成一个无参构造函数,自动生成
-
- 但是如果程序员写了至少一个构造函数,那么编译器就不会生成了。
-
- 在存在多个构造函数的情况下,编译器会在调用构造函数的时候,根据构造函数的参数自动匹
配相对应的构造函数进行调用
- 在存在多个构造函数的情况下,编译器会在调用构造函数的时候,根据构造函数的参数自动匹
-
构造函数格式
class 类名 { 类名(构造形参表) { //主要负责对象的初始化,即初始化成员变量 } };
2.对象的创建
- 在在栈区创建单个对象
类名 对象(构造实参表);
类名 对象 = 类名(构造实参表);
假设类名为Student
Student s = Student("蔡徐坤", 18, 10001); //Student s("蔡徐坤", 18, 10001);
- 在栈区创建多个对象(对象数组)
类名 对象数组(元素个数) = {类名(构造实参表),...}
Student sarr[3] = { Student("古丽娜扎",20,10002), Student("迪丽热巴",22,10003), Student("马尔扎哈",25,10004) };
- 在堆区创建单个对象
创建:类名 *对象指针 = new 类名(构造实参表);
销毁:delete 对象指针 //在堆区创建单个对象 Student *ps = new Student("林黛玉",19,10005); ps->who();//(*ps).who() 间接 delete ps; ps = NULL;
- 在堆区创建对象数组
创建:类名 *对象指针 = new 类名[元素个数]{类名(构造实参表),...}
销毁:Student* parr = new Student[3] { Student("潘金莲",30,10006), Student("扈三娘",35,10007), Student("孙二娘",31,10008) }; parr[0].who();//(parr + 0)->who() parr[1].who();//(parr + 1)->who() parr[2].who();//(parr + 2)->who() delete[] parr; parr = NULL;
- 小tips:malloc和new的区别:
-
- malloc申请的内存区域返回类型是void *类型,需强制转换为对应类型才可使用后;而new则
是自动生成所需要的类型。malloc申请内存需要手动计算大小,而new则自动计算相应的大
小
- malloc申请的内存区域返回类型是void *类型,需强制转换为对应类型才可使用后;而new则
-
- new会调用类构造函数为对象初始化,而malloc不会
- new会调用类构造函数为对象初始化,而malloc不会new会调用类构造函数为对象初始化,而malloc不会
3.构造函数参数的缺省
Student(const string name, const int age = 0, const int id = 0)
4.构造函数的重载
- C++中的函数参数支持重载,即函数名相同,但是参数列表不同,与返回值无关。构造函数和普通函数类似,也可以重载。
Student(const string name, const int age, const int id) Student(const string name, const int age) Student(const string name)
根据创建对象时的参数,调用不同的构造函数。
5.缺省(默认)构造函数
- 如果类中没有定义任何构造函数(无参构造函数、含参构造函数),编译器会为该类提供一个缺省
(无参)构造函数 -
- 对于基本类型的成员变量不能初始化
-
- 对于类类型的成员变量,会自动调用相应类的无参构造函数来初始化
- 如果类中自己定义了构造函数,无论是否有参数,编译器都不会再提供缺省的无参构造函数了
6.初始化表
- 除了使用构造函数来初始化类内的成员外,还有一种方式--初始化表
Student(const string name, const int age, const int no) :m_name(name), m_age(age), m_no(no) {}
多数情况下使用初始化表和在构造函数体中赋初值没有太大区别,可以任选一种方式,但是在某些特殊情况下必须要使用初始化表: - 如果有类类型的成员变量,而该类又没有无参构造函数,则必须通过初始化表来初始化该变量
- 如果类中包含"const"或"引用"型的成员变量,必须要使用初始化表来初始化。