构造函数
特点
- 构造函数是特殊的成员函数
- 创建类类型的新对象,系统自动会调用构造函数
- 构造函数是为了保证对象的每个数据成员都被正确初始化
- 函数名和类名完全相同
- 不能定义构造函数的类型(返回类型),也不能使用void
- 通常情况下构造函数应声明为公有函数,否则它不能像其他成员函数那样被显式地调用
- 构造函数被声明为私有有特殊的用途。
- 构造函数可以有任意类型和任意个数的参数,一个类可以有多个构造函数(重载)
默认构造函数
- 不带参数的构造函数
- 如果程序中未声明,则系统自动产生出一个默认构造函数
转换构造函数
- 单个参数的构造函数
- 将其它类型转换为类类型
- 类的构造函数只有一个参数是非常危险的,因为编译器可以使用这种构造函数把参数的类型隐式转换为类类型
代码
Test t(10); // 带一个参数的构造函数,充当的是普通构造函数的功能
t = 20; // 将20这个整数赋值给t对象
// 1、调用转换构造函数将20这个整数转换成类类型 (生成一个临时对象)
// 2、将临时对象赋值给t对象(调用的是=运算符)
赋值与初始化区别
在初始化语句中的等号不是运算符。编译器对这种表示方法有特殊的解释
Test t = 10; // 等价于Test t(10); 这里的=不是运算符,表示初始化。
t = 20; // 赋值操作
Test t2;
t = t2; // 赋值操作 t.operator=(t2);
可以通过重载赋值运算符来观察
Test& Test::operator=(const Test& other)
{
cout<<"Test::operator="<<endl;
if (this == &other)
return *this;
num_ = other.num_;
return *this;
}
explicit
- 只提供给类的构造函数使用的关键字。
- 编译器不会把声明为explicit的构造函数用于隐式转换,它只能在程序代码中显示创建对象
//test.h
explicit Test(int num);
//test.cpp
Test::Test(int num)
{
num_ = num;
cout<<"Initializing "<<num_<<endl;
}
//01.cpp
Test t = 10;//错误:不存在从int到test的转换
析构函数
- 函数名和类名相似(前面多了一个字符“~”)
- 没有返回类型
- 没有参数
- 析构函数不能被重载
- 如果没有定义析构函数,编译器会自动生成一个默认析构函数,其格式如下:
类名::~默认析构函数名( )
{
} - 默认析构函数是一个空函数。