类和对象(上)
一.类和对象–封装
概念:将数据和操作数据的方法有机结合,隐藏属性和实现细节
封装:类+访问限定符(类:可以将对象的属性和方法包装在一起),访问限定符控制程序是否能在类外直接对程序进行访问
Tips
a.两种定义方式:①类的定义和声明放在同一个类中②声明和定义分开(在声明时加类和类的作用域限定符)
b.在C++中class和struct的区别:在没有给访问权限的情况下,class默认的访问权限是private,stuct的默认访问权限是pubilc(为了兼容C语言)
c.类的成员变量最好不要跟参数列表中参数设置相同。
d.类的成员变量可以看成类的作用域成员函数的全局边变量
二.类的实体化
1.概念:用类的类型创建对象的过程
类的本身不占用空间,如果创建了对象才相当于开辟了空间
2.关于类的占用空间的问题
Q1:一个类的大小?(一个对象所占用空间大小?)
答:类的成员变量的类型所占空间之和(注意内存对齐)
Q2.一个类里没有成员变量,大小如何计算?(空类大小?)
答:在主流编译器(如VS)中为1个字节,原因是防止定义多个对象时,空类里没有成员变量所以所占空间大小为0,为了防止对象的地址叠加在一起,编译器设置变量和变量的距离为1,根据编译器的不同距离的设置也会不同。
Q3.简述内存对齐的规则?
1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。
2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.
typedef struct bb
{
int id; //[0]....[3]
double weight; //[8].....[15] 原则1
float height; //[16]..[19],总长要为8的整数倍,补齐[20]...[23] 原则3
}BB;typedef struct aa
{
char name[2]; //[0],[1]
int id; //[4]...[7] 原则1 double score; //[8]....[15]
short grade; //[16],[17]
BB b; //[24]......[47] 原则2
}AA;int main()
{
AA a;
cout<<sizeof(a)<<" "<<sizeof(BB)<<endl;
return 0;
}
//结果:24 48;
tips:1.,#pragma pack(1),告诉编译器,所有的对齐都按照1的整数倍对齐,换句话说就是没有对齐规则.
2,对于某个未知类的成员变量的函数如何计算类的大小?
offsetof(类的名字,类中某个成员变量) 这个宏定义可以计算改变量相对于类的起始位置所发生的偏移量。
3.大小端的概念:
大端(存储)模式:是指一个数据的低位字节序的内容放在高地址处,高位字节序存的内容放在低地址处。
小端(存储)模式:是指一个数据的低位字节序内容存放在低地址处,高位字节序的内容存放在高地址处。(可以总结为“小小小”即低位、低地址、小端)
如何测试?
#include <stdio.h>
int main()
{
int i = 1;
char *a = (char *)&i;
if(*a == 1)
printf("小端\n");
else
printf("大端\n");
return 0;
}
三.this指针
1.概念:this指向调用该函数的对象,this中存放的是该对象的地址,是成员函数的第一个默认形参,不需要用户传递
2.特点:传递方式:①通过ECX寄存器传递②通过参数压栈的方式
3.问题:Q1:This指针存在哪?
答:寄存器。
Q2:this指针是否可能为空?
答:可能。当成员函数被调用时必须存在对象或指向对象的指针,如ps=nullptr;可以拿ps调用函数,this指针放的地址是‘null’的地址因此不能对这个对象做任何操作因为不能对空解引用。