一.构造函数
(1)作用:初始化对象的属性
(2)构造函数特点:
1.当用一个类实例化一个对象时自动调用构造函数,
2.当类中没有构造函数的时候,系统会自动生成一个无参的构造函数,称为默认构造函数,只是这个构造函数的函数体是空的,有没有参数,不执行初始化操作
4.构造函数没有函数返回值,不具有任何类型
5.构造函数可以有任意类型和任意个数的参数,一个类可以有多个构造函数(重载)
6.函数名和类名完全相同(以便操作系统能识别它并把它作为构造函数处理)
7.构造函数不需用户调用,也不能被用户调用,对于带参数的构造函数,是在创建对象时把实参的值传递给构造函数相应的形参,把他们作为数据成员的初值,但无法采用常规的调用函数的方法给出形参(如Time(1,2,3)),而是采用下面这种形式:类名:对象名(实参1,实参2,。。。。)
示例:
class Time
{
public:
Time() //无参构造函数
{
hour_ = 0;
minute_ = 0;
sec_ = 0;
}
Time(int hour,int minute,int sec) //带参构造函数
{
hour_ = hour;
minute_ = minute;
sec_ = sec;
}
private:
int hour_;
int minmte_;
int sec_;
}
Time time1; //实例化对象时,
自动调用无参构造函数
,初始化成员变量
Time time2(1,2,3); //实例化对象时,
自动调用有参构造函数
,初始化成员变量
(3)构造函数初始化列表
示例:
class Time
{
public:
//用初始化表来实现对数据成员的初始化,这种方法不在函数体内对数据成员初始化,而是在函数首部实现
Time(int hour,int minut_,int sec) : hour_(h),minute_(m),sec_(s)
{
;
}
private:
int hour_;
int minmte_;
int sec_;
}
Time time1(1,2,3);
1.在类中若有
const成员变量
时,只能通过初始化列表初始化
2.
当类中的成员变量为引用时
也只能在初始化列表中初始化,在所有的构造函数中都要初始化
3
.当类中有另一个类的对象时
,要用初始化列表初始化,只要初始化要使用的构造函数即可
(4)注意点:
1.构造函数声明之后必须要实现
2.构造函数可以重载,根据类实例化对象时的方式选择调用构造函数
3.全局对象的构造函数先于main()函数执行
()使用默认参数的构造函数
示例:
class Box
{
public:
//带默认参数的构造函数
Box(int h = 10,int w = 10;int len = 10)
{
height_ = h;
width_ = w;
length_ = len;
}
private:
int height_;
int weight_;
int length_;
}
Box box1; //调用构造函数,各成员变量的值初始化为10
Box box2(5); //box2.height_ = 5;box2_weight_ = 10;box_3 = 10;
//此时若定义的类中有只有一个参数的构造函数,就不能再这
//样实例化对象了
一般不应同时使用构造函数的重载和有默认参数的构造函数
(5)转换构造函数:
1.作用:将一个其它类型的数据转换成一个类的对象,注意转换构造函数只能有一个参数,如果有多个参数就不是转换构造函数(当一个构造函数只有一个参数而且该参数又不是本类的const引用时(又不是拷贝构造函数时),这种构造函数称为转换构造函数)
2.如果不想让转换构造函数生效,也就是拒绝其它类型通过转换构造函数转换成本类型,可以在转换构造函数前加上
explicit
Test& Test::operator=(const Test& other)
{
if(this == &other)
{
return *this;
}
x_ = other.x_;
cout << "operator = Test" << endl;
return *this;
}
(6)在类中定义枚举
枚举属于类,不属于对象,枚举使用于所有的类型
(7)拷贝构造函数
1.当用已有的对象初始化一个新的对象会调用拷贝构造函数,当类中没有拷贝构造函数时,系统会自动生成一个拷贝构造函数,其作用只是简单复制类中每个数据成员
2.当对象做形参传递时会调用拷贝构造函数,但当对象的引用作形参传递的时候就不会调用拷贝构造函数
void func(Test a); //Test 为类,这时就会调用拷贝构造函数
void func(Test& a); //对象的引用作形参,这时就不会调用拷贝构造函数
3.当函数返回一个对象的时候会调用一个拷贝构造函数
示例:
Test :: Test(const Test& other) //拷贝构造函数没有返回值
{
if(this == other)
{
return *this;
}
x_ = other.x; //x_为Test中的成员变量
}
(8)深拷贝与浅拷贝
1.深拷贝和浅拷贝的前提是类中有指针的成员变量
2.默认的拷贝构造函数是浅拷贝
3.浅拷贝:让两个指针指向同一段内存空间,导致同一段空间释放两次
4.深拷贝:给每个指针分配空间
示例:
(9)构造函数的知识补充
1.两种使用构造函数来初始化对象的方式
//Stock为类名
Stock food = Stock("World Cabbage",250,1); //显式调用
Stock garment("Furry Mason",20,2); //隐式调用
二.析构函数
(1)一个对析构函数讲解很精辟的文档
(2)当对象的声明周期结束时,会自动执行析构函数,析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前完成一些清理工作,使这部分内存可以被程序分配给新对象使用
(3)当构造函数和析构函数遇上了指针,详见转载文档
(4)析构函数没有返回值和类型函数类型,没有参数(因此不能被重载)
(5)若用户没有定义析构函数,C++编译系统会自动生成一个析构函数,但它只是徒有析构函数的名称和形式,实际上什么操作都不做
(6)调用析构函数的次序正好和调用构造函数的次序相反:
先构造的后析构,后构造的先析构