当派生类中的成员变量和基类中同名,那么与函数同名一样,基类中的同名变量会被隐藏。也就是通过派生类对象无法访问基类的同名变量。
例一:
class base { public: int a; int b; base() { a=10; b=20; } virtual void fun() { fun2(); } void fun2() { cout<<a<<b<<endl;//line 3 cout<<this->a<<this->b<<endl; //line 4 } }; class derive:public base { public: int a; derive() { a=30; b=40; } void fun() { cout<<this->a<<this->b<<endl; fun2();//line 2 } }; int _tmain(int argc, _TCHAR* argv[]) { base *b=new derive; b->fun();// line 1 return 0; }
输出:30 40
10 40
10 40
下图为程序中继承示意图。b为base基类指针,指向derive派生类,那么派生类将从基类继承下来的那部分内容供基类指针b解引用。因此程序中line 1通过基类指针调用虚函数fun(),因为派生类中的虚函数覆盖了基类中的虚函数,所以vptr指向的虚函数表中的fun()是derive::fun()。因此line 1 行调用派生类中虚函数fun()。fun()函数中的this指针派生类的指针,因此this->a和this->b是派生类中的this,因此输出30,40。
line 2 行调用基类中的fun2,进入基类的函数中,line 3行的a和b指的是基类中的变量a,b,因此输出10,40;line 4行与line 3行一样,这里的this指针是基类的指针,即指针b。其实基类指针this和派生类指针this的值是一样的,只不过基类的this只能访问基类继承下来的成员,派生类的this可以访问基类继承的以及派生出来的成员,所以派生类指针访问成员变量a时,虽然有两个a,一个是base::a,一个是derive::a,但是derive::a的存在,使得base::a被隐藏了,所以派生类的this访问的是derive ::a。
例二:
class base { public: virtual void fun() { cout<<"base::fun"<<endl; } void fun2() { this->fun();// line 1 这里加不加this都一样,除非改成base::fun();或者不加虚函数,当不加虚函数的时候就跟成员变量类似的调用顺序,或者fun2是构造函数,构造函数中调用的是自己的本类的虚函数,跟对象类型无关 } }; class derive:public base { public: void fun() { cout<<"derive::fun"<<endl; } };
int _tmain(int argc, _TCHAR* argv[]) { base *b=new derive; b->fun2(); return 0; }
基类指针调用fun2()函数,line 1 行this->fun();这里的this指针是基类的指针,因为fun是虚函数,虚函数表中,派生类的虚函数覆盖了基类的虚函数,所以调用的还是派生类中的fun()函数。