c++面向对象编程(三)--多态

多态:接口的多种不同的实现方式即为多态,同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。


C++中,实现多态有以下方法:虚函数,抽象类,覆盖,模板(注意:重载和多态无关)。

virtual关键字:

编译器在执行过程中遇到virtual关键字的时候,将自动安装动态联编需要的机制,首先为这些包含virtual函数的类(注意不是类的实例)--即使是祖先类包含虚函数而本身没有--建立一张虚拟函数表VTABLE。在这些虚拟函数表中,编译器将依次按照函数声明次序放置类的特定虚函数的地址。同时在每个带有虚函数的类中放置一个称之为vpointer的指针,简称vptr,这个指针指向这个类的VTABLE。
一般来说一个对象的大小为所有成员变量的大小,但是当存在虚函数的时候即使这个类没有任何成员变量,他的对象的大小也不为0,为一个虚函数指针的大小。
当定义父类的一个函数为虚函数时,在子类中重载这个函数,用一个父类指针指向子类对象,并调用该函数的时候,调用的是子类的函数而不是父类的。如果父类中这个函数不是虚函数的话,调用的就是父类的函数了


请看一下例子:
//virtual members

</pre><pre name="code" class="cpp"><span style="font-size:24px;">#include <iostream.h>
class CPolygon {
protected:
	int width, height;
public:
	void set_values (int a, int b) {
		width=a;
		height=b;
	}
	virtual int area (void) {  return (0); }
};
class CRectangle: public CPolygon {
public:
	int area (void) { 
		return (width * height); 
	}
};

class CTriangle: public CPolygon {
public:
	int area (void) {
		return (width * height /2);
	}
};

int main () {
	CRectangle rect;
	CTriangle trgl;
	CPolygon poly;
	CPolygon * ppoly1 = ▭
	CPolygon * ppoly2 = &trgl;
	CPolygon * ppoly3 = &poly;
	ppoly1->set_values (4,5);
	ppoly2->set_values (4,5);
	ppoly3->set_values (4,5);
	cout << ppoly1->area() << endl;
	cout << ppoly2->area() << endl;
	cout << ppoly3->area() << endl;
	return 0;
}</span>

 
 

结果:

 20100

现在这三个类(CPolygon, CRectangle 和 CTriangle) 都有同样的成员:width, height,set_values() 和 area()。area() 被定义为 virtual 是因为它后来在子类中被细化了。你可以做一个试验,如果在代码种去掉这个关键字(virtual),然后再执行这个程序,三个多边形的面积计算结果都将是 0 而不是 20,10,0。这是因为没有了关键字 virtual ,程序执行不再根据实际对象的不用而调用相应 area() 函数(即分别为 CRectangle::area(), CTriangle::area() 和CPolygon::area()),取而代之,程序将全部调用 CPolygon::area(),因为这些调用是通过 CPolygon类型的指针进行的。因此,关键字 virtual 的作用就是在当使用基类的指针的时候,使子类中与基类同名的成员在适当的时候被调用,如前面例子中所示。

纯虚函数 virtual ()=0

virtual 函数返回值 函数名 (参数列表) =0 ;

接口函数留待子类来实现,如何一个类中有纯虚函数那么不能创建这个类的对象,但是能够创建这个类的指针

</pre><pre name="code" class="cpp">//virtual members
#include <iostream.h>
class CPolygon {
protected:
	int width, height;
public:
	void set_values (int a, int b) {
		width=a;
		height=b;
	}
	virtual int area (void) =0;
};

class CRectangle: public CPolygon {
public:
	int area (void) { return (width * height); }
};

class CTriangle: public CPolygon {
public:
	int area (void) {
		return (width * height /2);
	}
};
int main () {
	CRectangle rect;
	CTriangle trgl;
	CPolygon * ppoly1 = ▭
	CPolygon * ppoly2 = &trgl;
	ppoly1->set_values (4,5);
	ppoly2->set_values (4,5);
	cout << ppoly1->area() << endl;
	cout << ppoly2->area() << endl;
	return 0;
}

 
 


结果: 

20
10

用同一种类型的指针(CPolygon*)指向不同类的对象

抽象类:带纯虚函数的类

猜你喜欢

转载自blog.csdn.net/hgz_gs/article/details/51839507