1、构造函数初始化—-初始化列表
- 构造函数的初始化列表:
Student::Student(const string& name,const int id):name(name),id(id){}
概念上讲构造函数分两个阶段执行:(1)初始化阶段;(2)普通的计算阶段(函数体中的语句);初始化阶段发生在计算阶段之前。
如果初始化列表中没有显式提及每个成员,使用初始化变量一样的规则来初始化。运行该类型的默认构造函数,内置或复合型成员依赖对象的作用域:局部不被初始化,全局作用域则初始化为0。
什么时候必须使用初始化列表?没有默认构造函数的类类型的成员,以及const或引用类型的成员,必须在初始化列表中进行初始化。因为在构造函数体重赋值不起作用。
2、拷贝构造函数
- 为什么拷贝构造函数参数必须使用引用类型?如果不是引用类型,那么在传递实参的过程中会递归的调用该类的拷贝构造函数,造成死循环。引用类型只是传递一个指针。
3、构造函数和析构函数的封装
- 如何实现只能动态分配类对象,或者只能定义对象(只能在堆上或者栈上)?引用博客。
– 静态建立对象,A a;由编译器在栈中分配内存,通过移动栈顶指针,挪出适当的空间,在这片空间上再调用构造函数形成一个栈对象。这种方法直接调用类的构造函数。
– 动态建立对象,A* ptr = new A;使用new 运算符将对象建立在堆空间中,这个过程分为两步:1、执行operator new()函数,在堆空间中搜索合适的内存并分配;2、调用构造函数进行初始化。这种方法间接调用构造函数。
– 编译器为类对象分配栈空间时,会检查析构函数的访问性,如果析构函数是私有,那么编译器不会为对象分配空间。因此,将析构函数设为私有,类对象就无法建立在栈上了。
如果将operator new()重载并设为私有(同时私有operator delete),那么就不能将类对象建立在堆空间上了。