Day3-构造函数和析构函数
1.知识点总结:
共同点:
a.在类中如果没有提供这两个函数,系统默认给这两个函数提供空实现。
b.构造函数和析构函数必须声明在类全局的作用域(public)之下,否则外界是访问不到的
c.构造函数没有返回,也不用写void(1)构造函数---作用:初始化数据成员。
1.函数名与类名相同,可以有参数,可以发生重载
2.实例化对象时,由编译器自动调用一次,不需要手动调用
3.如何使用构造函数对数据成员进行初始化,注意初始化和赋值的区别。
(2)构造函数的分类以及调用。
a.构造函数的分类
1.按照参数分类:有参构造函数、无参构造函数(编译器默认提供)
2.按照类型分类:普通构造函数,拷贝构造拷贝构造函数
b.构造函数的调用方法
1.构造函数的的调用规则。
2.构造函数的调用方法
1.括号法---实例化对象直接加括号,括号里是构造函数要初始化或者进行赋值的参数列表,或为空
2.显式法---实际上是一个拷贝构造。
3.隐式法---实例化对象时,参数直接作为对象的初始化
(3)拷贝构造函数---重要
1.拷贝构造函数的调用3个时机
2.深拷贝与浅拷贝
3.两个问题:
1.拷贝构造函数中的const为什么不能去掉?熟知原理不能去掉,如果去掉,当传递的参数是右值的时候,非const左值引用不能绑定到 右值,所以就会报错或者说非const左值引用不能识别右值.
2.拷贝构造函数的引用符号为什么不能去掉?熟知原理引用符号不能去掉,如果去掉,使用拷贝构造函数的时候,会进行形参与实参的结 合,这个时候会调用拷贝构造函数,会继续满足拷贝构造函数的调用时机,会无限调 用下去,然后我们知道函数的参数会入栈,而栈是有大小的,所以最终回导致栈溢 出,然后程序就会崩溃,所以引用符号不能去掉
(4)析构函数---作用:类的数据成员的清理工作。
1.在函数名面前加~,就是析构函数,在类中只能有一个,不允许发生重载。
2.在类的对象销毁的时候自动调用
3.允许被显式调用,显式调用后,对象的数据会被清空,不建议使用。
一、简答题1.设A为test类的对象且赋有初值,则语句test B(A); 表示。
答:调用test类的拷贝构造函数,把A的内容当成对象B的初始值。
2.利用“对象名.成员变量”形式访问的对象成员仅限于被声明为 (1)的成员;若要访问其他成员变量,需要通过 (2) 函数
(1)public
(2)类封装的成员函数
3、浅拷贝与深拷贝区别?
1.浅拷贝:同一类型的对象之间可以赋值,可以使得两个对象的成员变量的值相同,但两个对象仍然是独立的,这种情况为浅拷贝。当类中有指针,并且指针指向的是动态分配的内存空间,析构函数做了动态内存释放的处理,可能会导致重释放的问题。
2.深拷贝:当类中有指针,并且此指针有动态分配空间,析构函数做了释放处理,往往需要自定义拷贝构造函数,自行给指针动态分配空间,进行内容拷贝,就是深拷贝。
二、写出下面程序结果。1、写出以下程序运行的结果。( )
#include <iostream>
using std::cout;
using std::endl;
class Sample
{
public:
Sample();
void Display();
private:
int i;
static int k;
};
Sample::Sample()
{
i=0;
k++;
}
void Sample::Display()
{
cout << "i=" << i << ",k=" << k << endl;
}
int Sample::k=0;
int main( )
{
Sample a, b;
a.Display();
b.Display();
return 0;
}
运行结果:
i=0,k=2 //k为2的原因,实例化了两个对象,静态变量k加了两次
i=0,k=2
2、设有如下程序结构:
class Box
{
//....
};int main()
{
Box A,B,C;