麻烦不同的多态性

时间:2018-03-24 12:40:11

标签: c++ polymorphism late-binding early-binding run-time-polymorphism

从我到目前为止学到的,有两种多态,编译时和运行时。 在编译时,多态函数或运算符由编译器解析,而在运行时,它在运行时解析。 compiile time polymorphism的示例包括函数和运算符重载,运行时多态包括函数重写和虚函数。 另外还有像早期绑定和后期绑定这样的情况,我将在稍后介绍。 请考虑以下代码:

for i, e in enumerate(lst):
    if e == search_value:
        lst.insert(i+1, value)

如果我这样做:

class base {
public:
    void Print() {
        std::cout << "This is parent class\n";
    }
};

class derived : public base {
public:
    void Print() {
        std::cout << "This is derived class\n";
    }
};

结果非常明显:

base b1;
b1.Print();
derived d1;
d1.Print();

当我使用指向基类的指针来操作这些函数时,真正的问题就开始了。

This is parent class
This is derived class

输出结果为:

base b1;
derived d1;
base* pb = &b1;
base* pb2 = &d1;
pb->Print();
pb2->Print();

这是由于Early binding,编译器检查调用该函数的对象的类型,而不是它处理的对象的类型。而且很明显它是在编译时完成的。现在,如果我在基类函数定义中使用This is parent class This is parent class 关键字,那么我可以轻松地完成上述操作而不会有任何麻烦,这是由于后期绑定,它根据对象的类型保存运行时的函数定义处理。这是运行时多态性的一个例子。

抱歉花了太长时间,我的问题是,这是我们实现运行时多态性的唯一方法吗?此外,如果函数重写是运行时多态性,那么前面的示例(即具有早期绑定的示例)也应该是运行时多态性,因为它也在执行函数重写。

1 个答案:

答案 0 :(得分:0)

没有什么会强迫您使用虚函数来实现运行时多态性。在性能关键代码中,经常会看到这样的事情,以避免虚函数调用的成本:

void foo(Base * _b)
{
   if(_b->typeID == TID_BASE)
   {
       b->bar();
   }
   else if(_b->typeID == TID_DERIVED)
   {
       static_cast<Derived*>(_b)->bar();
   }
}

其中type id是某种形式的枚举或唯一标识类型的指针。也就是说,我永远不会建议这样做,除非你实际测量到它在你的情况下会产生性能差异

关于你的上一个问题。不,这绝不是后期绑定,因为你根本没有覆盖任何功能。在您的示例中,Print类中有一个Base函数,Derived类中有一个Base函数。通过将您的对象转换为Base,您明确请求Printmvn dependency:tree 函数。