LInux C++学习day04 类定义与实例化 构造函数和初始化列表

一 类定义与实例化
1 类的一般语法形式
struct/class 类名:继承方式 基类,…{
访问控制限定符:
类名(形参表):初始化列表{}//构造函数
~类名(void){}//析构函数
返回类型 函数名(形参表){}//成员函数
数据类型 变量名;//成员变量
};
2 访问控制限定符
1)public:公有成员,任何位置都可以访问
2)private:私有成员,只有类内部的成员函数才能访问
3)protected:保护成员(后面讲)

3 构造函数(constructor)
1)语法
class 类名{
类名(形参表){
主要负责对象的初始化(初始化成员变量);
}
};
2)函数名和类名一致,没有返回类型
3)构造函数在创建对象时自动被调用,不能像普通函数一样显式的调用
4)在每个对象的生命周期,构造函数一定会被调用,但仅会被调用一次

eg:实现一个电子时钟类,使用构造函数初始化当前时间为系统时间,以秒为单位运行.
class Clock{
public:
Clock(time_t t){
tm* local = localtime(&t);
时 = local->tm_hour;
分 = local->tm_min;
秒 = local->tm_sec;
}
void run(void){
while(1){打印时间;计时+1s;sleep(1)}
}
private:
int 时,分,秒;
};
Clock c(time(NULL));
c.run();

4 对象的创建和销毁
1)栈区创建单个对象 //重点掌握
类名 对象(构造实参表);//直接初始化
类名 对象 = 类名(构造实参表);//拷贝初始化,实际初始化过程和上面一样.

2)栈区创建多个对象(对象数组)
类名 对象数组[元素个数] = {类名(构造实参表),…};

3)在堆区创建/销毁单个对象 //重点掌握
创建:类名* 对象指针 = new 类名(构造实参表);
注:new对象时,首先会在堆区分配内存,然后会自动调用构造函数,完成对象的创建;而如果是malloc仅能完成内存分配,不会调用构造函数,所以malloc不具备创建对象的能力。
销毁:delete 对象指针;

4)在堆区创建/销毁多个对象
创建: 类名* 对象指针 =
new 类名[元素个数]{类名(构造实参表),…};
销毁: delete[] 对象指针;

5 多文件编程:类声明和类的实现可以放在不同的文件中
1)类的声明放在头文件中:xx.h
2)类的实现放在源文件中:xx.cpp

二 构造函数和初始化列表
1 构造函数可以重载,也可以带有缺省参数
2 缺省(无参)构造函数
1)如果类中没有定义任何构造函数,编译器会为该类一个无参的构造,即为缺省构造函数:
–>对于基本类型的成员变量,不做初始化.
–>对于类类型的成员变量(成员子对象),将自动调用相应类的无参构造函数来初始化.
2)如果自己定义了构造函数,无论是否有参数,编译器都不会再提供缺省构造函数了.

3 类型转换构造函数(单参构造函数)
class 类名{
[explicit] 类名(源类型){…}
};
可以实现源类型变量隐式转换成当前类类型的对象。
注:可以使用explicit修饰类型转换构造函数,可以强制要求通过它实现类型转换的功能必须显式完成.

4 拷贝(复制)构造函数
1)用一个已存在的对象构造同类型的副本对象时,会调用该类的拷贝构造函数。
class 类名{
类名(const 类名&){…}
};
2)如果一个类没有定义拷贝构造函数,那么编译器会为该类提供一个缺省的拷贝构造函数:
–>对于基本类型成员变量,按字节复制
–>对于类类型成员变量(成员子对象),将自动调用相应类的拷贝构造函数来初始化。
注:实际开发中,一般不需要自定义拷贝构造函数,因为编译器缺省提供的拷贝构造函数已经很好用了.

3)拷贝构造函数调用时机
–》用已定义的对象作为同类型对象的构造实参
–》以对象形式向函数传递参数
–》从函数中返回对象(有时会被编译器优化掉)

5 初始化列表
1)语法
class 类名{
类名(形参表)
:成员变量1(初值1),成员变量2(初值),…{}
};
2)多数情况下使用初始化列表和在构造函数体中赋初值没有太大区别,两种写法可以任选,但是有些特殊场景必须要使用初始化列表:
–>如果有类类型的成员变量(成员子对象),并且希望以有参的方式来初始化(比如有些类没有无参构造),则必须要使用初始化列表来初始化.

猜你喜欢

转载自blog.csdn.net/weixin_43789711/article/details/90113423
今日推荐