上一篇博客对于类和对象还有一部分没有讲完。
一、类的实例化
用类型创建对象的过程,称为类的实例化。
- 类是对对象进行描述的,类似于模型,限定了类的成员,定义出一个类这只是声明,没有分配出实际的内存空间来存储它。
- 比如说我们建造房子之前,需要设计图,类就像是设计图,虽然有了建造的思路,但是没有实际的建筑实体。
二、类对象模型
2.1类的大小计算
首先,类大小的计算遵循结构体的对齐原则
类的大小为类中“成员变量”之和,注意空类的大小,空类比较特殊,编译器给了一个字节来标识空类。
2.2结构体的内存对齐规则
2.3类对象的存储方式
只保存成员变量,成员函数存放在公共代码段
三、this指针
3.1this指针的引出
class Student
{
public:
void Init(char name[20], char id[20])
{
_name = name;
_id = id;
}
void Printf()
{
count << _name << "_" << _id << endl;
}
private:
char _name[20];
char _id[20];
};
int main()
{
Student a1;
Student a2;
a1.Init(xie, 1);
a2.Init(a, 2);
return 0;
}
上面的代码我们定义了两个变量,我们在调用初始化函数时,编译器是如何确定它需要初始化的是a1变量还是a2变量呢?我们只传入了我们要初始化的内容,在函数中又没有传入指明修改的变量。其实在函数中编译器默认传入了一个this指针,只是没有显示,我们可以在函数中使用this指针,这个this指针就是变量的地址。
那么this指针存放在哪呢?
答案是在栈区,因为this指针是一个形参,但是有一些编译器会将this指针放在寄存器中,因为访问类中的成员变量都需要调用this指针,由于需要频繁的调用,所以将this指针存在寄存器中能够提高效率,到底是在栈区还是在寄存器中,这主要根据编译器的优化来决定。
四、类的6个默认成员函数
如果一个类中什么都没有,简称空类。
空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
4.1构造函数
4.1.1概念
构造函数是一个特殊的成员函数,名字与类名相同,在创建类类型对象时自动调用,以保证类中的数据成员有合适的初始值,并且在对象整个生命周期只调用一次。
4.1.2特性
构造函数虽然名称为构造,但是不是创建对象的,而是为对象内的数据初始化的。
- 函数名与类名相同
- 没有返回值(也不用写void)
- 对象实例化时自动调用
- 构造函数可以重载
- 如果类当中没有定义构造函数,C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不在生成默认构造函数。
C++类型分类:
内置类型:int、double、char、指针等
自定义类型:struct、class
默认生成的构造函数不会对内置类型进行处理,自定义类型成员会去调用他的默认构造函数。(假如该自定义类型由默认生成的构造函数同样遵循上面要求,如果该自定义类型内是内置类型同样不做处理)这是C++早期设计的缺陷,默认生成构造函数,本来应该内置类型一并处理,所以在C++11中打了一个补丁允许给对象的数据成员给缺省值。下面代码有展示。
class Time
{
public:
date()
{
_year = 1;
_month = 1;
_day = 1;
}
date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year = 1;//这里不是初始化而是给缺省值
int month;
int day;
};
int main()
{
Time a1;//此时调用会不明确因为有一个无参的构造函数还有一个全缺省的构造函数,所以调用函数不明确。
return 0;
}
4.1.3默认构造函数
默认构造函数的特点:不传参数就可以调用的
默认构造函数有三类:
- 我们不写构造函数,编译器自动生成的默认构造函数。
- 我们写的,全缺省构造函数
- 我们写的,无参构造函数