问题:C++中的空类,默认情况下会产生哪些类成员函数?
系统默认的缺省构造函数和复制构造函数(拷贝构造函数)
系统默认提供的析构函数.
系统默认的拷贝赋值函数(运算符重载函数):用于同类对象之间的赋值.
系统默认的取值运算:当对类的对象进行取地址(&)时会被调用.
1.构造函数法和析构函数存在的必要性和作用:
(1).构造函数的必要性和作用(用构造函数确保初始化):
解决同种类型的不同对象的初始化问题.保证每个对象的数据成员都有何时的初始值。
(2).析构函数的必要性和作用(用析构函数确保清除):
回收内存和资源,通常用于释放在构造函数或对象生命期内获取的资源。
当对象超出它的定义范围时,编译器自动调用析构函数.
2.构造函数和析构函数的种类:
(1).一个类可以有多个构造函数(即构造函数的重载).
缺省构造函数:不带任何参数的构造函数,.
当编译器需要创建一个对象而又不知任何细节时,缺省的构造函数就显得非常重要.在一个构造类型中没有构造函数时,编译器会自动创建一个,然而,一旦有其他的构造函数之后就没有缺省构造函数.
重载的构造函数:带参数的构造函数.
属于类成员函数的重载,通过参数的个数,类型和顺序形成重载的条件.其中特殊情况是:
如果类中有其他的构造函数的话,系统就不会提供默认的缺省构造函数以构造对象.
如果类中构造函数带有默认参数的话,防止出现重载二义性而出错.
类中的构造函数形成重载时,注意防止重载函数中存在隐式类型转换而出现重载的二义性.
复制构造函数(拷贝构造函数):
分为系统提供默认的复制构造函数(即浅拷贝或者全盘拷贝),以及自定义的复制构造函数(即深拷贝或者部分拷贝).
(2).一个类只有一个析构函数(即析构函数不存在重载),
析构函数也分为系统默认的和自定义的析构函数(完成指定的其他功能).
3.关于复制构造函数(拷贝构造函数)具体知识点:
(1).定义格式:
类名 (类名+&对象)
{
}
特点:无返回值,参数只有且只能是同类对象的引用.
解疑:为什么不允许定义这种形式 A(A copy) 的拷贝构造函数?
这个拷贝构造函数在参数传递的过程中又要调用拷贝构造函数本身,而调用拷贝构造函数时又要先进行参数传递,参数传递又要调用拷贝构造函数。。。。。。于是陷入不停的分配堆栈的无限递归中,而每次压栈过程中又嵌套了压栈,致使每一次的压栈都不能完成,因此,编译器通过不了这种形式的拷贝构造函数。
(2).拷贝构造函数(拷贝构造函数)和拷贝赋值函数(赋值运算符重载)的比较:
不同的地方:
a.拷贝构造函数是在对象被创建并用另一个已经存在的对象来初始化它时调用的;
如string s1 = "Hello World";
string s2 = s1; //等价于string s2(s1);
b.拷贝赋值函数只能把一个对象赋值给另一个已经存在的对象,使得那个已经存在的对象具有和源对象相同的状态。
如 string s3;
s3 = s1;
相同的地方:
默认的拷贝构造函数和默认的赋值构造函数均采用“按成员拷贝”默认方式来实现。
以类String的两个对象a、b为例。假设a.m_data的内容为“Hello”,b.m_data的内容为“world”。现将a赋值给b,默认赋值函数的“按成员拷贝”意味着执行b.m_data=a.m_data。这将造成三个错误:
(1)b.m_data原持有的内存没有被释放,造成内存泄漏。
(2)b.m_data和a.m_data指向同一块内存区域,a或b任何一方变动都会影响另一方
(3)在对象被析构时,m_data被delete了两次。
4.构造函数的初始化列表知识点:
1).初始化列表的构造顺序:
初始化列表中个数据成员的构造顺序与其声明的顺序一致.而不是按照出现在初始化列表的顺序相关.
2.)必须使用初始化列表的情况?
引用(const)成员和reference类型的成员只能被初始化而不能在初始化列表外进行赋值操作.
类的继承中基类的构造函数必须通过初始化列表来调用(先调用基类构造函数,然后才是自身的构造函数).
类的聚合中聚合类的嵌套对象的构造可以放在其构造函数体内进行赋值而不必一定初始化才行,和普通的成员变量一致.