对象的初始化和清理是两个非常重要的安全问题,一个对象或者变量没有初始状态,对其使用后果是未知,同样的使用完一个对象或变量,没有及时清理,也会造成—定的安全问题。 C++利用了构造函数和析构函数解决上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。
构造函数:主腰作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。 ?
对象的初始化和清理工作是编译器强制要我们做的事情,因此如果我们不提供构造和析构,编译器会提供的构造函数和析构函数是空实现。
构造函数和析构函数的语法
?构造函数:
1、没有返回值,也不用也void;
2、函数名与类名一致;
3、构造函数可以有参数,也可以重载;
4、程序在调用对象时候会自动调用构造函数,无须手动调用,而且只会调用一次。
?析构函数:
1、没有返回值,也不用也void;
2、函数名与类名一致,但需要在函数名前加上波浪号:~;
3、析构函数不能带参数,所以不能发生函数重载;
4、程序在对象销毁前时候会自动调用析构函数,无须手动调用,而且只会调用一次。
构造函数的分类
按参数分为:有参构造和无参构造
按类型分为:普通构造和拷贝构造
class A
{
public:
A(){}//无参构造函数
A(int a){}//有参构造函数
A(const A &p)//拷贝构造函数,将对象p的属性传入该构造函数,在其实现过程中可以使用p的属性
{
a=p.a;
b=p.b;
}
private:
int a;
int b
};
?构造函数的调用
1、括号法
如下图所示,其调用比较简单,也是最常用的方法:
class A
{
public:
A()//无参构造函数
{
cout<<"无参构造函数调用"<<endl;
}
A(int x,int y)//有参构造函数
{
a=x;
b=y;
}
A(const A &p)//拷贝构造函数
{
a=p.a;
b=p.b;
}
private:
int a;
int b
};
int main()
{
括号法:
A p1;//调用A()无参构造函数
A p2(10,20);//调用A(int x,int y)有参构造函数
A p3(p2);调用A(const A &p)拷贝构造函数,即p3这个对象将p2的所有属性都拷贝了一份
}
?????????注意
无参构造的调用不能带括号,不能A p1(),这样写编译器会认为是一个函数声明。
2、显示法
A p1;//无参构造还是老样子
A p2 = A(10,20);//调用有参构造函数
A p3 = A(p2);//调用拷贝构造函数
?????????注意
? ? ? ? 上图中等号右侧的A(10,20)和A(p2)属于匿名对象,其特点是当前执行结束后,会被系统会立即回收掉。
3、隐式转换法
A p1;//无参构造还是老样子
A p2 = {10,20};//调用有参构造函数,这是多参数情况,如果有参构造只有一个参数,就不用大括号了。
A p3 = p2;//调用拷贝构造函数
?
|