C++内存模型this指针解析

this指针

  • 学习过C++面向对象的同学大概都知道,在一个类中,只有非静态成员变量是属于这个类对象的,而成员函数和静态成员都是只有一份的(换句话说,如果你实例化一个对象,那么成员函数是不会占用这个对象的内存空间的)

  • class Student {
    public:
        Student(){};
        ~Student(){};
        void setAge(int tmpAge){
            age=tmpAge;
    	}
        int getAge() {
            return age;
        }
        int age;
    };
    
    int main() {
        Student s1,s2;
        s1.setAge(100);
        s2.setAge(30);
        
        return 0;
    }
    
  • 对于上面这段代码来说,如果说成员函数只有一份,那么成员函数应该如何区分是哪个实例化对象调用的自己呢?

  • 比如上面这个setAge函数,他并不知道是对象s1还是对象s2调用的自己

  • 所以这时,this指针的概念就被引入了:当实例化一个对象时,就会自动产生一个this指针指向该对象,然后在调用函数时,编译器会隐式地将this指针传到那个非静态成员函数,从而让非静态成员函数知道是谁在调用自己

this指针使用时机

  • class Person {
    public:
        void setName(string name) {
            this->name = name;	//这是this指针的一种用法,用于在形参和成员变量重名的时候,来实现区分
        }
        Person& PersonAddPerson(Person p)	//用于返回对象本身时候使用,这样可以实现链式编程
    	{
    		this->age += p.age;
    		//返回对象本身
    		return *this;
    	}
    private:
        string name;
    };
    
    int main() {
        Person p1;
        p1.setName("Tom");
        
        Person p2(10);
        //链式编程思想
    	p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
    	cout << "p2.age = " << p2.age << endl;
        return 0;
    }
    
    //对于上面这段代码p.setName("Tom")来说,编译器会看成是这样:p.setName(&p, "Tom");
    
  • 上面这段代码很好的展示了this指针的使用场景,最常用的就是以上两个场景

  • 你会发现当使用到==“对象自身”的语义时,你就会想到使用this指针来指代对象自身==

  • this其实就是指向对象的一个指针,就像上面的最后一行注释写的那样,编译器在发现你调用某个非静态成员函数时,会隐式地传入对象自身的地址,并且在每个非静态成员函数的参数列表中加上一个该类的指针叫做this,这些都是你不可见的

this指针注意事项

注意1:this指针只针对非静态成员函数有效

  • this指针只针对非静态成员函数有用,对于静态成员函数则不起作用

  • 这是因为静态成员函数与某个对象无关,它是属于整个类的,所有对象共用一个静态成员函数

  • 这个静态成员函数在你对象实例化出来之前就已经存在了,而this指针是随着对象的实例化而出现的,所以静态成员函数不可以使用this指针(你可以把它理解为根本没有指针传入),请看下面这个例子

  • class Person {
    public:
    
    	void ShowClassName() {
    		cout << "我是Person类!" << endl;
    	}
    
    	void ShowPerson() {
    		cout<<"this指针所放的地址为:"<<this<<endl;
    	}
        static void func() {
            cout<<this->mAge<<endl;
        }
    public:
    	int mAge;
    };
    
  • 编译时会出错,报错如下:

  • test.cpp: In static member function 'static void Person::func()':
    test.cpp:15:15: error: 'this' is unavailable for static member functions
       15 |         cout<<this->mAge<<endl;
          |
    

注意2:注意this有可能是空指针

class Person {
public:
    Person() {
        cout<<"这是Person类的构造函数"<<endl;
    }
    ~Person() {
        cout<<"这是Person类的析构函数"<<endl;
    }
	void ShowClassName() {
		cout << "我是Person类!" << endl;
	}

	void ShowPerson() {
		cout<<"this指针所放的地址为:"<<this<<endl;
	}
    static void func() {
        cout<<"静态成员函数"<<endl;
    }
public:
	int mAge;
};

void test01()
{
	Person * p = NULL;
	p->ShowPerson();	//注意,空指针是可以调用成员函数的
    p->func();	//同样的,也可以调用静态成员函数
}
  • 对于这个test函数中的p来说,其实p本身就可以看做是一个this指针,都指向这个实例化的对象,只不过这个实例化是nullptr,所以this指针的值也是nullptr
  • 我一开始会想:这个对象根本就为空,不存在,为啥可以通过指针调用函数呢?其实前面已经说过答案了,这些函数其实都本不属于这个类本身,所以其实是否实例化对象都不是很重要,函数就在那里,只不过区别是传入的this指针是不是nullptr的区别罢了
  • 但是需要注意的是,使用一个为空的this指针时,需要特别注意判断为空,否则容易发生非法操作

this指针小测验

  • 希望大家可以通过这个小测验来更好地理解this指针

开始咯!!!

  • 什么是this指针?它有什么作用?
    • 答:this指针是一个指向当前对象的指针,在每个非静态成员函数中都被隐式地传递给函数。它的作用是让成员函数能够访问该对象的成员变量和成员函数。
  • 如何在C++中使用this指针?
    • 答:在C++中,可以使用this关键字来访问该指针。例如,可以使用this->成员变量名来访问对象的成员变量。在成员函数中,可以使用this指针来避免参数名和成员变量名相同的冲突,或者用于返回自身。
  • 在成员函数中,this指针可以被显示调用吗?为什么?
    • 答:在成员函数中,this指针可以被显式调用,但是不推荐这样做。因为this指针在每个非静态成员函数中都被隐式地传递给函数,所以不需要显式地使用它。如果需要显式地使用this指针,可能会导致代码可读性降低,增加出错的可能性。
  • 静态成员函数中是否有this指针?为什么?
    • 答:静态成员函数中没有this指针。因为静态成员函数是属于类而不是属于对象的,所以它没有this指针。在静态成员函数中不能访问非静态成员变量和非静态成员函数,只能访问静态成员变量和静态成员函数。
  • this指针是否占用对象的存储空间?
    • 答:可以通过sizeof验证,this指针是不占用对象的,它是编译器自动为我们产生的,不在类的内部
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值