上溢、下溢,this指针

1.上溢、下溢:

对整数,溢出指代数值:小于最小值为下溢,大于最大值为上溢

对浮点数,溢出指绝对值:绝对值小于浮点数所能表示的最小值,为下溢,当作 0;绝对值大于浮点数所能表示的最大范围,为上溢,当作 INF。

根据具体符号的不同,又分为:正上溢、正下溢、负上溢、负下溢

2.this指针:

this指针是类的一个自动生成、自动隐藏的私有成员,它存在于类的非静态成员函数中,指向被调用函数所在的对象的地址。全局仅有一个this指针,当一个对象被创建时,this指针就指向对象数据的首地址。

2.1 this指针的特性:

此部分转自:https://blog.csdn.net/loving_forever_/article/details/51547371

1)this指针的类型是一个类类型 * const, 这表示什么呢?如果你想在你的成员函数之中改变你的this指针的指向,很显然,做不到!

2)不过当你在使用sizeof操作符的时候千万要注意,不要把this指针的大小考虑进去,这是为什么呢?this指针本身不占用大小,它并不是对象的一部分,因此不会影响sizeof的结果。

3)this指针是类成员函数的第一个默认隐含参数,因此不需要你显示地传入,你在类成员函数之中可以直接使用this指针。

4)this指针的作用域是在非静态函数的内部,在成员函数(非静态)开始前构造,在成员函数(非静态)结束后消除。(下面会分析为什么是在非静态函数内部才能使用)

5)this指针的传入方式,这里不得不提函数的调用约定_thiscall,如果参数确定,那么this指针是通过ecx传递给被调用者的,若参数不确定,那么this指针在所有参数压入之后在压入。

(_thiscall的调用约定如下:

这 是 C++ 语言特有的一种调用方式,用于类成员函数的调用约定。如果参数确定,this 指针存放于 ECX 寄存器,函数自身清理堆栈;如果参数不确定,this指针在所有参数入栈后再入栈,调用者清理栈。__thiscall 不是关键字,程序员不能使用。参数按照从右至左的方式入栈。

6)this指针不能再初始化列表之中使用,原因是在初始化列表之中,类的对象还没有创建,编译器不知道对象的结构,因此不知道应该为其分配多大的空间。

2.2 this指针与类的存储关系:

此部分转自:https://blog.csdn.net/better1914/article/details/62043410

1)在类中数据是怎么存储的? 
用类去定义对象时,系统会为每一个对象分配存储空间。如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间。 
如图:模型一 

模型二: 

可以通过求类的大小来测试编译器采用的哪种模式。如果大于double类型的字节数,则采用的第一种模式,等于double字节则采用的第二个模式。

#include<iostream>
using namespace std;
const double PI = 3.1415926;
class circle
{
private:
    double radius;
public:
    void Init(double _radius)
    {
        radius = _radius;
    }
    void Print()
    {
        cout << "area=" << PI*radius*radius << endl;
    }
};
int main()
{

    cout << sizeof(circle) << endl;
    system("pause");
    return 0;
}
//输出为8字节,刚好是数据部分的double类型的大小

结论:C++编译系统正采用模式二的,每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间。 
那么问题来了。。所的有对象都调用共用的函数代码段,如何区分的呢。这个功劳就是c++中this指针的了! 
c++设置了 this 指针,this 指针指向调用该函数的不同对象。。

2)this指针作用

#include<iostream>
using namespace std;
const double PI = 3.1415926;
class circle
{
private:
    double radius;
public:
    void Init(double _radius)
    {
        radius = _radius;
    }
    void Print()
    {
        cout << "area=" << PI*radius*radius << endl;
    }
};
int main()
{

    circle cir1, cir2;
    cir1.Init(23.2);
    cir2.Init(13.6);
    cout << sizeof(circle) << endl;
    cir1.Print();
    cir2.Print();
    system("pause");
    return 0;
}

如上代码,创建两个对象cir1,cir2。通过上述介绍,我们直到c++编译器,将函数部分作为公共代码区域。通过cir1.Init()使得函数init与对象cir1绑定。通过cir2.Init()使得函数init与对象cir2绑定。类成员函数的形参和类的属性,名字相同,而不同对象可以实现不同数据的操作这是怎么实现的呢? 

其实,每个成员函数都有一个this指针,this指针指向调用对象。即,某个对象正在调用成员函数那么this指针就指向哪个对象。this指针并不是对象本身的一部分,不影响sizeof的结果(已证明)。 


3)this指针如何产生? 
然而我们在编程时,并没有写入有关this指针的任何声明和定义,那么this指针又是如何产生的呢? 
this指针是类成员函数的第一个默认隐含参数,编译器自动维护传递。

猜你喜欢

转载自blog.csdn.net/qq_16334327/article/details/80481828