This指针,静态成员函数和非静态成员函数

1.virtual与静态函数 
C++中,静态成员函数不能被声明为virtual函数。 
例如,下面的程序会编译失败。

#include  
class Test  
{  
   public:  
      // 编译错误:static成员函数不能声明为virtual     
      virtual static void fun()  { }  
};  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

同样地,静态成员函数也不能被声明为const和volatile. 
下面的程序也会编译失败。

#include  
class Test  
{  
   public:  
      // 编译错误: static成员函数不能为const  
      static void fun() const { }  

      // 如果声明为下面这样,是可以的。  
      const static void fun() {}  
      或类似于  
      const static int fun() { return 0; }  
};  

 

2.为何static成员函数不能为virtual 
1. static成员不属于任何类对象或类实例,所以即使给此函数加上virutal也是没有任何意义的。 
2. 静态与非静态成员函数之间有一个主要的区别。那就是静态成员函数没有this指针。 
虚函数依靠vptr和vtable来处理。vptr是一个指针,在类的构造函数中创建生成,并且只能用this指针来访问它,因为它是类的一个成员,并且vptr指向保存虚函数地址的vtable. 
对于静态成员函数,它没有this指针,所以无法访问vptr. 这就是为何static函数不能为virtual. 
虚函数的调用关系:this -> vptr -> vtable ->virtual function 
通过下面例子可以确定,当类增加了一个虚函数后,类的大小会增大4字节(指针的大小). 
class Test 

public: 
int _m; 
}; 
sizeof(Test) = 4;

加入虚函数后, 
class Test 

public: 
int _m; 
virtual void fun(); 
}; 
sizeof(Test) = 8

3.为何static成员函数不能为const函数 
当声明一个非静态成员函数为const时,对this指针会有影响。对于一个Test类中的const修饰的成员函数,this指针相当于Test const , 而对于非const成员函数,this指针相当于Test . 
而static成员函数没有this指针,所以使用const来修饰static成员函数没有任何意义。 
volatile的道理也是如此。 
4.静态成员函数只能访问静态成员变量->静态成员函数没有this指针 

5.静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问。->静态成员函数不属于任何对象,而是属于类的。

 

 

关于this指针的一个精典回答:

 

当你进入一个房子后,
你可以看见桌子、椅子、地板等,
但是房子你是看不到全貌了。
对于一个类的实例来说,
你可以看到它的成员函数、成员变量,
但是实例本身呢?


this是一个指针,它时时刻刻指向你这个实例本身。
 
个人理解:


(ps:class类就好比这座房子,this就好比一把钥匙,通过钥匙来打开了这座房子的门,那么里面的东西就随意你取用了)


      this是指向实例化对象本身时候的一个指针,里面存储的是对象本身的地址,通过该地址可以访问内部的成员函数和成员变量。
    为什么需要this?因为this作用域是在类的内部,自己声明一个类的时候,还不知道实例化对象的名字,所以用this来使用对象变量的自身。在非静态成员函数中,编译器在编译的时候加上this作为隐含形参,通过this来访问各个成员(即使你没有写上this指针)。例如a.fun(1)<==等价于==>fun(&a,1)  
    this的使用:1)在类的非静态成员函数中返回对象的本身时候,直接用return *this(常用于操作符重载和赋值、拷贝等函数)。


2)传入函数的形参与成员变量名相同时,例如:this->n = n (不能写成n=n)


举例程序:


class Point  
{   
    int x, y;  
public:  
    Point(int a, int b) 
    { x=a; y=b;}  


    Void MovePoint( int a, int b)
    { x+=a; y+=b;}  


    Void print()
    { cout<<"x="< ;} 
 
}


void main( )  
{  
     Point point1( 10,10);  
     point1.MovePoint(2,2);  
     point1.print( );  
}  


1.对象point1调用MovePoint(2,2)的时候,即将point1对象的地址传递给了this指针,this指针就是这个对象首元素的地址,像数组
名其实就是数组第一个元素的地址一样。


2.编译器编译后的原型应该是void MovePoint(Point *this, int a, int b)


3.在函数体中可以写成{this->x += a; this->y += b;}


4.也等价为point1.x += a;point1.y += b。(指针变量通过->访问成员变量(函数),对象通过.)

你可能感兴趣的:(C++学习)