类是什么呢?
类我们可以认为是C语言中结构体的升级版本,因为C语言中的结构体只能定义变量,而在类中我们还可以定义函数。
为什么要出现类呢?
首先我们先说一下C++和C语言的一些区别
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成
比如我们养了一堆小狗,我们就应该把他们的信息记录下来
struct Dog
{
int age;//年龄
int weight;//体重
char varity[10];//种类
};
但是现实中我们的一堆小狗不仅仅有信息要记录,他们还有技能比如说都会跑都会叫,这个变量就无法帮助我们记录了
这时候就需要用到我们的成员函数,C++中定义类的关键字默认为class,当然也可以用struct.后面我们再谈他们的区别。
class Dog
{
void run();
void bark();
int age;//年龄
int weight;//体重
char varity[10];//种类
};
class是关键字, Dog是类名 ,下面的变量叫做数据成员,而两个函数就叫做成员函数。
我们养的一堆狗就可以统称为一类,而其中单独的一只就可以叫做一个对象。
下面我们说说类的访问限定符
类有三个访问限定符
1.public:公有
2.protected:保护
3.private:私有
我们养的每一只狗都是一个对象,他们的种类年龄体重都是不同的这是他们自己的,是他们私有的。 但他们却同时可以叫和跑
此时叫和跑两个成员函数就是大家都有的就叫做公有的。
关于访问限定符的说明
1.public修饰的成员再类外可以被直接访问。
2.protected和private则不能再类外被直接访问
3.访问权限作用域从该访问限定符出现的位置开始到下一个访问限定符出现为止。
4.这点就来解释struct和class在C++的区别
在C++中struct既可以用来定义结构体也可以用来定义类但是他与class不同的是
class定义的类如果不加访问限定符默认为私有的,而struct默认为公有的。
类的作用域:
类的定义也就定义了一个新的作用域,所有的成员都在这个作用域里,在类外定义成员需要使用::作用域解析符指明成员属于哪个类型。
类的实例化:
用类创建对象的过程就被成为类的实例化
class Dog
{
public:
void run();
void bark();
private:
int _age;
int _weight;
char varity[10];
};
int main()
{
Dog d1;
Dog d2;
return 0;
}
这就是实例化出了两个对象d1和d2。
实例化之后成员变量是独立的成员函数是共享的之前我们也提过了。
需要注意的是
类只是一个模型,我们创建一个类,系统并不会分配实际的内存空间去存储他
一个类可以实例化多个对象,实例化出来的对象才会占用实际的物理空间,存储成员变量
我们可以这样理解,我们要造一堆坦克,首先要设计出一个坦克的图纸或者说是模型,然后才能根据我们设计的图纸和模型进行建造,
我们可以把图纸理解成一个类。建成的一个个坦克车就是我们通过图纸这个类实例化出来的对象
如何计算类的大小呢?
其实类的大小就是该类中成员变量之和,但是要注意内存对齐。
类的内存对齐和结构体的内存对齐规则一致
1.第一个成员在偏移量为0的地址处
2.其他成员变量要对齐到某个数字的整数倍的地址处
对其数=编译器默认的一个对齐数与该成员大小的较小值
VS中默认是8,gcc中默认是4
3.结构体总大小为:最大对齐数整数倍(意思就是如果按照规则算出来结构体大小为15但最大对齐数为4那么结构体实际总大小则为4的倍数,就会按16计算)。
4.如果出现嵌套,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数的整数倍(包括嵌套的结构体)。
那么问什么要存在内存对齐呢?
可以提高内存的访问效率,内存按整数倍位置访问。
this指针:
this指针就是C++编译器给每个成员函数增加了一个隐藏的指针参数,让改指针指向当前对象,在函数中变量所有操作都是通过this指针去访问,只不过我们看不见操作而已,编译器会帮我们完成这个操作。
为什么要有this指针呢?
先看看我们之前的一份代码
class Dog
{
public:
void run()
{
cout<<_age<<"-"<<_weight<<endl;
}
void bark();
private:
int _age;
int _weight;
char varity[10];
};
int main()
{
Dog d1;
Dog d2;
d1.run();
d2.run();
return 0;
}
我们通过Dog类实例化出两个对象d1和d2。
然后我们分别调用d1.run()和d2.run()
函数中没有关于对象进行区分,那我们调用d1.run()。为什么不会输出d2的信息呢?
就是因为this指针的存在,其实内部是
class Dog
{
public:
void run(Dog* this)
{
cout <<this-> _age << "-" <<this-> _weight << endl;
}
void bark();
private:
int _age;
int _weight;
char varity[10];
};
int main()
{
Dog d1;
Dog d2;
d1.run();
d2.run();
return 0;
}
this指针的特性:
1.this的类型是类类型*const
2.只能在成员函数内部使用
3.时刻指向当前对象,不属于对象的一部分,不会影响sizeof的结果
4.this指针成员函数第一个隐含的指针形参,一般由编译器通过exc寄存器自动传递,不需要用户进行传递。
这样我们就对类和对象有了基本的认识。