构造函数和析构函数
构造函数——对对象初始化,开辟空间
- 构造函数名字必须与类名相同
- 不能有返回值,甚至是void也不行
- 在建立对象时可自动调用
形式:
类名 对象名 (实参表)
complex A(1,1);
类名 * 指针变量名 =new 类名(实参表)
complex *pa=new complex(1.1,2.2);
4.构造函数一般声明为公有成员,但它不需要被显示调用,在定义对象时被调用且只执行一次
5.编译器默认生成的构造函数可为成员开辟空间,但不能赋值(无参)
6.构造函数可以不带参数
用成员初始化列表对数据成员初始化
在构造函数函数首部实现实现初始化
类名::构造函数名(参数表):成员初始化列表
complex ::complex (double r,int i):R(r),I(i);
成员初始化列表形式:
数据成员1(初始化值1),数据成员2(初始化值2)...//成员之间用逗号,分隔
注意:使用成员初始化列表,并且函数的声明与定义分离时,成员初始化列表要写在函数声明处,函数的声明与定义不可以分离写在两个文件中
对于用const修饰的数据成员或引用类型的成员是不能直接赋值的,只能用成员初始化列表对其进行初始化
class A
{
public:
A(int x1):x(x1),rx(x),pi(3.14)//pi是const修饰的成员
{}
private:
int x;
int rx;
const double pi;
};
构造函数的重载
- 使用无参数的构造函数创建对象时,后面不应带()
如:
Date d1;//不能写成Date d1();
- 如果构造函数的类声明与定义分离,那默认参数应在声明原型时指定。
- 注意避免无参构造函数与完全默认参数构造函数同时使用,否则会产生二义性
- 在一个类中定义了一个全是默认参数的构造函数后,不能在定义重载构造函数
complex (int r=0,int i=0);
complex(int r);// 会产生二义性
拷贝构造
拷贝构造函数的特点
- 只有一个参数——对象的引用
- 每个类必须有一个,如果没有,系统会自动生成
自定义拷贝构造函数
类名::类名(const 类名& 对象名)
使用:
- 类名 对象2(对象名);代入法
- 类名 对象2=对象1;赋值法
调用拷贝构造函数的3种情况:
- 用类对象初始化另一个对象
- 函数形参是类对象
- 函数返回值为类对象
静态成员
静态成员属于类,所有对象共享
静态成员的初始化应在类外单独进行且应在定义对象之前
//数据类型 类名::静态数据成员名=初始值
int A::count=0;//不必再加static
class A
{
private:
static int count;
}
私有静态不能在类外单独访问
静态成员函数没有this指针,静态成员函数一般不访问非静态成员,若访问,只能通过对象名(指针)访问。
析构函数
- 析构函数与类名相同,前面必须加~
- 不返回任何值
- 不能被重载
- 撤销对象时,编译器会自动调用析构函数
- 每个类必须有一个析构函数,如果没有,编译系统会自动生成
- 如果构造函数中使用new的话,析构函数中需调用delete释放空间
调用析构函数的情况
- 主函数结束
- 对象在函数内定义,函数结束
- 用new创建对象指针,用delete释放时,delete会自动调用析构函数