
多态从实现的角度可以划为两类:编译时多态和运行时多态。
编译时的多态性:就是在程序编译的时候,也就是生成解决方案的时候就决定要实现什么 *** 作。
运行时的多态性:就是指直到系统运行时,才根据实际情况决定实现何种 *** 作。
1、多态实现形式不同:
编译时的多态是通过静态连编来实现的;运行时的多态是用动态连编来实现的。
2、多态性通过方式不同:
编译时的多态性主要是通过函数重载和运算符重载来实现的;运行时的多态性主要是通过虚函数来实现的。
扩展资料:
静态多态性又称编译时的多态性。静态多态性的函数调用速度快、效率高但缺乏灵活性,在程序运行前就应决定执行的函数和方法。
动态多态性的特点是:不在编译时确定调用的是哪个函数,而是在程序运行过程中才动态地确定 *** 作所针对的对象。又称运行时的多态性。动态多态性是通过虚函数(virtual function)实现的。
所谓多态,就是使用基类的指针访问子类的函数,具体代码如下:
#include <iostream>using namespace std;
const float PI = (float)314159;
class Shape{
public:
virtual float CalCircumference()=0;
virtual float CalArea()=0;
};
//圆形
class Roundness: public Shape{
public:
Roundness(float r):radius(r)
{}
virtual float CalCircumference()
{
return 2 PI radius;
}
virtual float CalArea()
{
return PI radius radius;
}
private:
float radius;
};
//正方形
class Square: public Shape{
public:
Square(float w):width(w)
{}
virtual float CalCircumference()
{
return 4 width;
}
virtual float CalArea()
{
return width width;
}
private:
float width;
};
//长方形
class Rectangle: public Shape{
public:
Rectangle(float w, float h):width(w), hight(h)
{}
virtual float CalCircumference()
{
return 2 (width + hight);
}
virtual float CalArea()
{
return hight width;
}
private:
float width;
float hight;
};
void main()
{
Shape roud = new Roundness(3);
Shape squ = new Square(3);
Shape rang = new Rectangle(3, 4);
cout<<"圆形的周长:"<<roud->CalCircumference()<<" 面积:"<<roud->CalArea()<<endl;
cout<<"正方形的周长:"<<squ->CalCircumference()<<" 面积:"<<squ->CalArea()<<endl;
cout<<"长方形的周长:"<<rang->CalCircumference()<<" 面积:"<<rang->CalArea()<<endl;
}
bar(a+1, b+1, a+SQ-1, b+2SQ-1);
bar(a-SQ+1, b+1+SQ, a, b-1+2SQ);
}
void shap2(int x, int y)
{
int a=xSQ+BX, b=ySQ+BY;
setfillstyle(1, SHAP2);
bar(a+1, b+1, a+SQ-1, b+2SQ-1);
bar(a+SQ, b+SQ+1, a+2SQ-1, b+2SQ-1);
}
先给个小例子。
#include <iostream>
using namespace std;
class Base
{
public:
virtual void DoWork()
{
cout << "Base" << endl;
}
};
class DeriveFirst : public Base
{
public:
virtual void DoWork()
{
cout << "DeriveFirst" << endl;
}
};
class DeriveSecond : public Base
{
public:
virtual void DoWork()
{
cout << "DeriveSecond" << endl;
}
};
void Work(Base pBase)
{
// 这里的pBase表现出了多态,对于pBase的不同实际类型,这里会做不同的事
pBase->DoWork();
}
int main()
{
Base pFirst = new DeriveFirst();
Work(pFirst);
Base pSecond = new DeriveSecond();
Work(pSecond);
return 0;
}
多态:在Work函数中的“pBase->DoWork();”这一行代码就表现出了pBase的多态性,当pBase的实际类型是DeriveSecond时,它调用的是DeriveSecond版本的DoWork,当它是DeriveFirst时,它调用的是DeriveFirst版本的DoWork。
同化效应:老实说之前没见过这个名字。猜测它所指的应该是在Work中,不需要关心pBase的具体类型,对于合法的以Base为基类的任何类的对象,在这里都能一致的处理它,只需要调用DoWork就能在运行时达到我们想要的效果。
虚函数:这是C++用来实现多态的机制。如果你想了解整个虚函数的实现机制建议你去看《深入理解C++对象模型》这一本书。这里简单说一下,一般编译器都是通过虚函数表的方式来实现虚函数,即对于拥有虚函数的类,它内部会存储一张函数映射表,当你调用某一个函数时,它会根据这个函数对应的索引找到正确的函数版本。
#include<iostream>
using namespace std;
class shape
{
public:
shape(int x,int y):a(x),b(y){}
virtual int area()const{return 0;}//这里const是表示什么意思? 这个表示这是常函数,意思是这个函数保证不会修改类中的成员
private:
int a,b;
};
class circle:public shape
{
public:
circle(int x,int y,int r):shape(x,y),r(r){}//为什么在circle函数中用到了x,y?并且在后面对数据修改时还有shape(x,y) //这里确实没有用到x,y 只是因为父类shape有这两个成员,所以象征性的也赋下值,不过也是因为这个shape抽象度有问题,没有很好地覆盖circle的属性,所以circle自己又搞了个r成员
virtual int area()const {return 314rr;}
private:
int r;
};
void f(shape&s)
{
cout<<sarea()<<endl;
}
int main()
{
circle c(2,5,4);
f(c);
return 0;
}
//最后的运行结果与基类中的x,y好像没关系。请具体解释一下
//没关系,分析见上
不是使用了虚函数就能实现运行时的多态性,实现运行时多态性要满足以下4个条件:
1要有一个继承层次
2在基类要定义虚函数
3在派生类中要对基类中的虚函数进行重定义
4要通过基类指针(或基类引用)来调用虚函数
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)