我对运行时多态性感到有些困惑。如果我错了,请纠正我,但据我所知,运行时多态意味着函数定义将在运行时得到解决。
举个例子:
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。
那么模糊性存在于哪里?
在什么情况下,函数定义会在运行时得到解决?
答案 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
并查看输出。因此,在运行时(程序运行时)确定适当的函数调用。