今天宠物迷的小编给各位宠物饲养爱好者分享c 多态的作用的宠物知识,其中也会对c++多态实现原理(C++多态原理)进行专业的解释,如果能碰巧解决你现在面临的宠物相关问题,别忘了关注本站哦,现在我们开始吧!
1.在编译期间实现多态多态是指在不同的条件下表现出不同的状态,C++中通过重载函数的方法可以在编译期间实现多态。在编译时编译器会根据参数列表的不同寻找合适的函数。
2.使用虚函数实现多态C++中运行时多态可以通过声明一个虚函数来实现。虚函数分为纯虚方法和半虚方法,纯函数父类没有实现版本,完全交给子类,且必须实现。半虚函数父类可以实现...
3.虚函数的实现原理一个类中如果有虚函数声明,那么这些函数会由一个虚函数表来维护 1)...
多态是一种不同的对象以单独的方式作用于相同消息的能力,这个概念是从自然语言中引进的。例如,动词“关闭”应用到不同的事务上其意思是不同的。关门,关闭银行账号或关闭一个程序的窗口都是不同的行为;其实际的意义取决于该动作所作用的对象。
大多数面向对象语言的多态特性都仅以虚拟函数的形式来实现,但C++除了一般的虚拟函数形式之外,还多了两种静态的(即编译时的)多态机制:
2、模板:例如,当接受到相同的消息时,整型vector对象和串vector对象对消息反映是不同的,我们以关闭行为为例:
vector vi; vector names; string name("VC知识库");
vi.push_back( 5 ); // 在 vector 尾部添加整型
names.push_back (name); // 添加串和添加整型体现差别的潜在的操作
静态的多态机制不会导致与虚拟函数相关的运行时开。此外,操作符重载和模板两者是通用算法最基本的东西,在STL中体现得尤为突出。 那么接下来我们说说以虚函数形式多态: 通常都有以重载、覆盖、隐藏来三中方式,三种方式的区别大家应该要很深入的了解,这里就不多说了。 许多开发人员往往将这种情况和C++的多态性搞混淆,下面我从两方面为大家解说: 1、 编译的角度 C++编译器在编译的时候,要确定每个对象调用的函数的地址,这称为早期绑定(early binding)。2、 内存模型的角度为了确定对象调用的函数的地址,就要使用迟绑定(late binding)技术。当编译器使用迟绑定时,就会在运行时再去确定对象的类型以及正确的调用函数。而要让编译器采用迟绑定,就要在基类中声明函数时使用virtual关键字(注意,这是必须的,很多开发人员就是因为没有使用虚函数而写出很多错误的例子),这样的函数我们称为虚函数。一旦某个函数在基类中声明为virtual,那么在所有的派生类中该函数都是virtual,而不需要再显式地声明为virtual。 那么如何定位虚表呢?编译器另外还为每个类的对象提供了一个虚表指针(即vptr),这个指针指向了对象所属类的虚表。在程序运行时,根据对象的类型去初始化vptr,从而让vptr正确的指向所属类的虚表,从而在调用虚函数时,就能够找到正确的函数。 正是由于每个对象调用的虚函数都是通过虚表指针来索引的,也就决定了虚表指针的正确初始化是非常重要的。换句话说,在虚表指针没有正确初始化之前,我们不能够去调用虚函数。那么虚表指针在什么时候,或者说在什么地方初始化呢? 答案是在构造函数中进行虚表的创建和虚表指针的初始化。还记得构造函数的调用顺序吗,在构造子类对象时,要先调用父类的构造函数,此时编译器只“看到了”父类,并不知道后面是否后还有继承者,它初始化父类对象的虚表指针,该虚表指针指向父类的虚表。当执行子类的构造函数时,子类对象的虚表指针被初始化,指向自身的虚表。 要注意:对于虚函数调用来说,每一个对象内部都有一个虚表指针,该虚表指针被初始化为本类的虚表。所以在程序中,不管你的对象类型如何转换,但该对象内部的虚表指针是固定的,所以呢,才能实现动态的对象函数调用,这就是C++多态性实现的原理。总结(基类有虚函数):1、 每一个类都有虚表。2、虚表可以继承,如果子类没有重写虚函数,那么子类虚表中仍然会有该函数的地址,只不过这个地址指向的是基类的虚函数实现。如果基类3个虚函数,那么基类的虚表中就有三项(虚函数地址),派生类也会有虚表,至少有三项,如果重写了相应的虚函数,那么虚表中的地址就会改变,指向自身的虚函数实现。如果派生类有自己的虚函数,那么虚表中就会添加该项。3、派生类的虚表中虚函数地址的排列顺序和基类的虚表中虚函数地址排列顺序相同。
最简单的做法是在结构体里存函数指针,然后初始化结构体的时候将函数的地址赋值给它。
复杂一点的,就得按照C++的多态原理,用虚函数表(其实就是能记录函数名对应的函数地址就好)记录每种结构体的成员函数地址,然后每个结构体里多存一个虚函数表的地址。。。然后调用函数的时候查到函数地址强转成函数类型然后调用。。。这个可以自己研究一下c++的虚函数表机制。
C++中,实现多态有以下方法:虚函数,抽象类,重载,覆盖,模版。
多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的。
两种方式都实例化了C类的对象,但是引用不同,第一种只能调用A类里定义了方法,第二种A/B/C三个类里面定义的方法都可以调用。将第一种new出来的对象a进行强转为C类应用后即可调用A/B/C类的所有方法,因为他自己本来就是C类对象。多态是指,如果A类定义了方法fun()而后B类或C类重写了方法fun(),则new的C类对象只会调用最后重写的fun()方法,即B类或C类的fun()方法。示例:
public
class
车(){
public
void
发动(){靠某种动力发动};
public
void
运行(){可以跑};
public
void
装载(){可以装物品};
}
public
class
汽车()
extends
车{
public
void
发动(){靠发动机发动};
public
void
装载(){可以载人};
}
public
class
公交车()
extends
汽车{
public
void
装载(){可以载很多人};
public
void
报站(){到公交站可以报站让乘客下车};
}
车
a
=
new
公交车();//实例化了一个公交车,但是我们只知道它是车;
公交车
c
=
new
公交车();//实例化了一个公交车,而且我们知道它是公交车;
a.发动();//a是车,可以调用“车”类定义的“发动”方法,实际上它是公交车,公交车也是汽车,所以是靠发动机发动;
c.发动();//c是公交车,公交车是汽车,可以调用继承自“汽车”类的重写的“发动”方法,靠发动机发动;
a.运行();//a是车,可以调用“车”类定义的“运行”方法,可以跑;
c.运行();//c是公交车,公交车也是车可以调用继承自“车”类定义的“运行”方法,可以跑;
a.装载();//a是车,可以调用“车”类定义的“装载”方法,实际上它是公交车,所以它可以载很多人;
c.装载();//c是公交车,可以调用“公交车”类重写的“装载”方法,可以载很多人;
c.报站();//c是公交车,到公交站可以报站让乘客下车;
((公交车)a).报站();//a本来是公交车,但是我们只知道它是车,不一定会报站,现在把它强转为公交车,那我们就知道他是公交车了,可以报站,到公交站可以报站让乘客下车。
总体而言就是:对象能调用哪个方法是根据我们所知道的它是哪个类来看,而调用该方法实际执行的操作是根据它实际上是哪个类来看。子类继承父类就有了父类的方法,而重写父类的方法就改掉了实际执行的操作。这就是多态。
希望对你有帮助。
下一篇
关于宠物龟疾病护理方法介绍