运行时多态意味着什么?

时间:2010-08-11 09:46:03

标签: c++ inheritance runtime polymorphism

我对运行时多态性感到有些困惑。如果我错了,请纠正我,但据我所知,运行时多态意味着函数定义将在运行时得到解决。

举个例子:

class a
{
a();
~a();
void baseclass();
}

class b: class a
{
b();
~b();
void derivedclass1();
}

class c: class a
{
c();
~c();
void derivedclass2();
}

致电方法:

b derived1;
a *baseptr = &derived1; //here base pointer knows that i'm pointing to derived class b. 
baseptr->derivedclass1();

在上面的调用方法中,基类知道它指向派生类b。

那么模糊性存在于哪里?

在什么情况下,函数定义会在运行时得到解决?

6 个答案:

答案 0 :(得分:10)

此代码在运行时调用f()的正确版本,具体取决于实际创建的对象(A或B)的类型 - 没有“歧义”。在编译时无法识别该类型,因为它是在运行时随机选择的。

struct A {
   virtual ~A() {}
   virtual void f() {}
};

struct B : public A {
   virtual void f() {}
};


int main() {
   A * a = 0;
   if ( rand() % 2 ) {
      a = new A;
   }
   else {
      a = new B;
   } 
   a->f();   // calls correct f()
   delete a;
}

答案 1 :(得分:5)

提供的示例中不存在歧义。

如果基类与派生类具有相同的函数名,并且如果以指定的方式调用,则它将调用基类的函数而不是派生的类。

在这种情况下,您可以使用virtual关键字,以确保从当前指向的对象调用该函数。它在运行期间得到解决。

Here你可以找到更多解释..

答案 2 :(得分:1)

转过来

void baseclass();

virtual void baseclass();

在派生类b和c中覆盖它。然后

b *derived1 = new derived1 ();
a *baseptr = derived1; //base pointer pointing to derived class b. 
baseptr->baseclass();

将调用derived1定义,表示运行时多态性。并记住在Base中使析构函数虚拟化。 Some basic reading material for polymorphism

答案 3 :(得分:1)

运行时意味着只有在运行时才能知道确切的方法。考虑这个例子:


class BaseClass
{
public:
  virtual void method() {...};
};

class DerivedClassA : public BaseClass
{
  virtual void method() {...};
};

class DerivedClassB : public BaseClass
{
  virtual void method() {...};
};

void func(BaseClass* a)
{
  a->method();
}

当你实现你的:: func()时,你并不确切知道BaseClass * a指向的实例的类型。它可能是DerivedClassA或DerivedClassB实例等 您应该意识到,运行时多态性需要语言的特殊支持(并且可能需要一些调用“虚拟”函数的开销)。在C ++中,您通过声明基类“virtual”的方法并使用公共继承来“请求”动态多态。

答案 4 :(得分:0)

您需要在基础和每个派生类中声明一些有用的业务方法。然后你有代码,如

 a->someMethod();

现在,a指针可能指向任何派生类的实例,因此指向的类型必须确定调用哪个someMethod()。

答案 5 :(得分:0)

让我们进行实验

#include <iostream>
using namespace std;
class aBaseClass
{

public:

    void testFunction(){cout<<"hello base";}///Not declared as virtual!!!!

};
class aDerivedClass:public aBaseClass
{
public:
    void testFunction(){cout<<"hello derived one";}
};

class anotherDerivedClass:public aDerivedClass
{
public:
    void testFunction(){cout<<"hello derived two";}

};
int main()
{
    aBaseClass *aBaseClassPointer;
    aBaseClassPointer=new aDerivedClass;
    aBaseClassPointer->testFunction();
}

上面的代码不支持运行时多态性。让我们运行并分析它。 输出是

hello base

只需将void testFunction(){cout<<"hello base";}行更改为virtual void testFunction(){cout<<"hello base";}中的aBaseClass即可。运行并分析它。我们看到实现了运行时多态性。调用适当的函数是在运行时确定的。

再次将主要功能中的行aBaseClassPointer=new aDerivedClass更改为aBaseClassPointer=new anotherDerivedClass并查看输出。因此,在运行时(程序运行时)确定适当的函数调用。