目录
先说结论,不管对于静态还是非静态成员,其都是存储在内存中的代码区。
对此,我们可以使用代码加以验证:
- class C
- {
- public:
- void func()
- {
- cout << "c" << endl;
- }
- int c;
- };
-
- int main()
- {
- C i;
- const char* str = "hello";//常量字符串,常量区
- printf("func: %p\n", &(C::func));
- printf("str: %p\n", str);
- return 0;
- }
我们发现,func的地址比存在常量区的str还要低。而地址空间中,代码区就在常量区下方(低地址处)。该文章中第一张图片可以表明地址空间存储结构:Linux——进程地址空间
因为上述发现,更加佐证了类成员函数存放在代码区。
当我们通过同一个类实例化出多个对象时,为了最大化的节省空间资源,每个对象各自有一份成员变量,但共享代码区的成员函数。
可以用一张图表明类中成员存储结构:
当我们通过实例化的对象调用成员函数时,如果按照上图存储结构,因为所有的对象共享一份成员函数,那么调用的成员函数无法确定自己内部使用的成员变量是属于哪个具体对象的。
对此,this指针的用途就显现出来了:确定调用该函数的实例化对象。
当调用成员函数时,this指针指向调用该函数的对象。函数使用成员变量时,通过this指针指向的对象找到该变量的位置。由此,当调用函数时,只会使用本对象的数据而不会发生错乱。
对于静态成员函数而言,其参数中没有this指针。
为什么静态成员函数没有this指针?——因为作为静态成员函数,它是被整个类共享的,不存在需要识别具体对象的情况。
由此我们可以解释为什么静态成员函数可以直接通过类名访问。因为静态成员函数不需要this指针指向具体对象,换句话说,静态成员函数内部不应该使用实例化对象的成员变量,因为无法通过this指针指向具体变量,势必报错。
程序员的问题是你无法预料他在做什么,直到为时已晚——Seymour Cray(超级计算机之父)
如有错误,敬请斧正