
举个例子:
int i;
如上,随便定义一个变量,现在,能改变变量i的地址么。原则上,从高级语言的角度来说,改变i的地址是不可能的,因为i的地址是编译器设定的。同样,如果i是某个类的对象,一样不能改变i的地址,而this指针就是对象地址的别名,因此通常无法改变。说“通常”是指在C++语言这个层面上是无法改变的,除非对C++编译器编译完的目标代码进行修改。另外,如果想改变this的指向,也不需要直接修改this,而只需要将this加上某个偏移值就行了,比如(this+12)->funname();但是要考虑到指针的安全性问题。
this指针的用处:一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。 例如,调用dateSetMonth(9) <===> SetMonth(&date, 9),this帮助完成了这一转换
调用对象的任何函数都会在函数内部产生一个this指针,this指针是个常量指针,由编译器编译时生成。this指针只在对象内部可见,所以调用时你也无法访问this指针,更不需要。
this指针用于对象内部的函数访问当前对象的其他成员,同时可起到一定的提高阅读性的作用,当在函数内访问另一个同类对象的成员时可以区分开来,比如拷贝函数中当需要将形参对象的成员复制到本地对象成员时。
比如
MyClass(const MyClass & obj){
this->Value=objValue;
}
显然使用this->Value 比直接使用Value更直观地表明等号左侧的Value是当前对象的Value。
另外,顺便提一下,this指针的地址是每个函数开始时通过相对地址计算出来的,而不是传递进来的。
在箭头函数出现之前,每一个新函数根据它是被如何调用的来定义这个函数的this值:如果是该函数是一个构造函数,this指针指向一个新的对象在严格模式下的函数调用下,this指向undefined如果是该函数是一个对象的方法,this指针指向这个对象如果该函数通过 call、apply 等方法调用,则它的 this 指向该方法传入的第一个参数值但是箭头函数在调用的时候并没有 this 绑定过程,它的 this 指向在他被创建的那一刻就决定了。例如你在全局环境下定义一个箭头函数的时候,它的 this 就会指向 window 对象:<img src="https://pic2zhimgcom/50/v2-b21d8f6533e52ba88e4b054b54e9407a_720wjpgsource=1940ef5c" data-caption="" data-size="normal" data-rawwidth="616" data-rawheight="60" class="origin_image zh-lightbox-thumb" width="616" data-original="https://pic3zhimgcom/v2-b21d8f6533e52ba88e4b054b54e9407a_rjpgsource=1940ef5c"/>
子类构造的时候会自动调用基类的构造函数 并且是有顺序的
调用完构造函数的顺序 :基类 子类 子子类
不仅构造函数 析构函数也这样 子类对象析构时自动调用基类的析构函数
顺序与构造函数顺序相反 :子类基类
关于显示调用基类的构造函数,是不可行的。必须用初始化表的形式调用基类构造函数,才能正确的把子类继承下来的父类的成员初始化了。如果在子类构造函数体内显式调用了基类构造函数的话,那么该构造函数就会对一个在子类构造函数内存空间内的一个临时对象进行了初始化,因为没有取得正确的对象(子类对象)的指针。所以构造了半天白费。等子类构造函数退出,则统统丢失。所以,基类构造函数在没拿到正确this指针的情况下,没有办法正确赋值。下面是例子:
#include <iostream>
#include<string>
using namespace std;
class CLSA{
public:
CLSA( )
{}
CLSA( int i ) : m_j(i) {}
int getA()
{return m_j;}
private:
int m_j;
};
class CLS: public CLSA
{
public:
CLS( int i,int j );
/CLS()
{
CLS(0);
}/
int m_i;
};
CLS::CLS( int i,int j ) : m_i(i) ,CLSA(j)
{
CLSA(10);//这里显式调用基类构造函数给临时对象进行赋值的,但是等CLS构造函数退出返回后,临时对象丢失。所以, 这个函数没有给真正的对象赋值。因为没有取得正确的this地址。
}
int main()
{
CLS obj(2,3);
cout << objm_i << endl; //输出结果是什么?CLSA(j),
cout<<objgetA();
return 0;
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)