前言
这期将会讲解关于类的计算类对象的大小,this指针,类和对象(1)和(2)的作业部分。下期的话将会讲解类里面的6个默认成员函数,也是难点所在(类和对象的两大难点之一——另一个难点是构造函数的初始化列表)
计算类对象的大小
跟C++的结构体一样也需要内存对齐
类对象和类的大小只算成员变量,不算成员函数 成员函数是放在代码段的
类的大小跟类对象的大小是一样的
内存对齐:
1.对齐数 = 编译器默认的对齐数 和 成员中最大的那个 当中的较小者
2.结构体的总大小 = 对齐数的整数倍
3.第一个成员开头的起始位置是0
4.其他所有成员变量的起始位置都是要是对齐数的整数倍地方
要注意的是:这里的对齐数跟硬件读取一次读多少是没啥关系,但是这个对齐数能提高硬件读取的效率 (这也就是为什么要内存对齐)
没有成员变量的类对象,也会开辟1字节的空间,为了占位,表示对象存在 此时没有存储有效数据
eg: 比如class list{ public: void Init(){} };
this指针
一个类里面的对象都是用的一样的成员函数,但是成员函数可以识别出是哪个对象调用的它–这就多亏了this指针
其实,在对象调用成员函数时,编译器会自动添加实参和形参(this)–参数有时只看()里面的,不能一概而论
比如: void Init(Date*this)--这里写成(Date*const this)是等价的,因为this的性质 {…………}
但是我们自己在写的时候,不能添加上(也就是this不能在形参和实参显式传递),但是,在函数内部可以使用this(也就是在函数内部可以显式使用)
eg:if(this->_a == 1)
注意:this指针的类型是 类型*const,因为不能给this指针赋值
引申:
const在
*
后面的话,是限制的指针,在*
前面的话,是限制的指针指向的内容
语法形式 能否修改指针的指向(地址)? 能否通过指针修改指向的对象? const int *ptr
可以 不可以 int *const ptr
不可以 可以 const int *const ptr
不可以 不可以
问:this存在哪里?
this是形参,所以this指针是跟普通参数一样存在函数调用的栈帧里面的
比如:在VS下,this指针是存储在ecx(寄存器)里的
类和对象(1)和(2)的作业部分
在C++中的结构体是否可以有成员函数?(B)
A.不可以,结构类型不支持成员函数
B.可以有
C.不可以,只有类允许有成员函数
C++里面的结构体也可以拥有类的特性
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:
void Print()
{
cout << "Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();//这个要用反汇编看,其实并没有对空指针进行解引用--本质还是要看反汇编
return 0;
}
这个题是选C
// 2.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->PrintA();
//p调用PrintA,不会发生解引用,因为PrintA的地址不在对象中,p会作为实参传递给this指针
return 0;
}
这个题选B,因为_a那里是this->_a,对空指针进行解引用了,会导致运行崩溃
下面描述错误的是(C)
A.this指针是非静态成员函数的隐含形参//静态成员函数没有this指针,只有非静态成员函数才有,且为隐藏指针
B.每个非静态的成员函数都有一个this指针//非静态成员函数的第一个参数就是隐藏的this指针
C.this指针是存在对象里面的//this指针在非静态的成员函数里面,对象不存在
D.this指针可以为空//只是不能赋值为空而已
补充:this指针保证每个对象拥有自己的数据成员,但共享处理这些数据的代码