C++

虚函数的迟绑定,重写和隐藏相关

2010/12/10

虚拟和多态

分析类关系如下所示,分析输出结果,总结虚拟多态的实现方式,并且把构造F类的对象时候,每次父类构造函数执行时候对虚函数表的修改,并体会在构造函数中调用虚函数有什么特点。

|----------------------------------|

|   \函数 |                        |

|类名\名字|f() |s() |t() |m() |x() |

| A       |V   |V   |    |V   |    |

|-----------------------------------

| B       |覆盖|    |隐藏|    |    |

|----------------------------------|

| C       |    |重写|隐藏|    |    |

|----------------------------------|

| D       |覆盖|重写|    |    |    |

|----------------------------------|

| E       |    |    |    |    |    |

|----------------------------------|

| F       |覆盖|重写|隐藏|    |    |

|----------------------------------|

代码实现:

#include <iostream>
using namespace std;
/*----BASIC A BEGIN----*/
class A
{
public:
	virtual void f();
	virtual void s();
	virtual void m();
	void t();
	void x();
private:
	int a,b,c;
};

void A::f()
{
	cout<<"the virtual f() in A is called"<<endl;
}

void A::s()
{
	cout<<"the virtual s() in A is called"<<endl;
}

void A::m()
{
	cout<<"the virtual m() in A is called"<<endl;
}

void A::t()
{
	cout<<"the t() in A is called"<<endl;
}

void A::x()
{
	cout<<"the x() in A is called"<<endl;
}
/*------BASIC A END-----*/

/*-----DERIVED B BEGIN---*/
class B:public A
{
public:
	void f();
};

void B::f()
{
	cout<<"the virtual f() in B is called"<<endl;
}
/*-----DERIVED B END-----*/

/*-----DERIVED C BEGIN---*/
class C:public B
{
public:
	void s();
};

void C::s()
{
	cout<<"the virtual s() in C is called"<<endl;
}
/*-----DERIVED C END-----*/

/*-----DERIVED D BEGIN---*/
class D:public C
{
public:
	void f();
	void s();
};

void D::f()
{
	cout<<"the virtual f() in D is called"<<endl;
}

void D::s()
{
	cout<<"the virtual s() in D is called"<<endl;
}
/*-----DERIVED D END-----*/

/*-----DERIVED E BEGIN---*/
class E:public D
{
public:
	E(){};
};
/*-----DERIVED E END-----*/

/*-----DERIVED F BEGIN---*/
class F:public E
{
public:
	void f();
	void s();
};

void F::f()
{
	cout<<"the virtual f() in F is called"<<endl;
}

void F::s()
{
	cout<<"the virtual s() in F is called"<<endl;
}

/*-----DERIVED F END-----*/
int main()
{
// basic function has achieve
	A *p= new A();
	B *q= new B();
	C *k= new C();
	D *l= new D();
	E *e= new E();
	F *f= new F();
// END
	A *m=p;//可以给以 p q k l e f

	m->f();
	m->m();
	m->s();
	m->t();
	m->x();

	f->f();
	f->s();

	e->x();

	l->s();
	l->f();

	k->s();

	q->f();

	p->f();
	p->m();
	p->s();

	return 0;
}

首先说明一下多态性。

多态性

当C++编译器在编译的时候,发现Animal类的breathe()函数是虚函数,这个时候C++就会采用迟绑定(late binding)的技术,在运行时,依据对象的类型(在程序中,我们传递的Fish类对象的地址)来确认调用的哪一个函数,这种能力就做C++的多态性。

然后是隐藏和覆盖

派生类覆盖虚函数的前提是以下三个条件:

1.该函数是否与基类的虚函数有相同的名称。

2.该函数是否与基类的虚函数有相同的参数个数及相同的对应参数类型。

3.该函数是否与基类的虚函数有相同的返回值或者满足赋值兼容规则的指针,引用型的返回值。

所谓隐藏就是覆盖了一个基类的虚函数,而基类含有重载函数,派生类就间接的隐藏了基类中同名函数的所有其他重载形式。 这个派生类的这个实现隐藏和覆盖的函数也是虚函数。