不用虚函数机制实现运行时多态

今天在豆瓣看到一个好友讨论构造函数、运算符重载等等相关概念。于是想到C++里面实现运行时多态只能用虚函数机制吗?一直以来从各种学习材料上都是这么学的:提到多态要知道有编译时和运行时之分;运行时多态和晚期联编要用到虚函数机制……等等,好像这俩概念是连体的一样。实际上C++的多态机制只是用vtable和虚函数帮我们做了很多事情而已,不用虚函数,也可以实现多态——当然,这样一来有些功能可能就用不了了,比如我曾经在概念上犯过SB的dynamic_cast。

那么要怎么实现呢?假设手头有两个类,Base和从它继承出来的Derive,两者都定义了名为Foo()的成员函数。我们期望下面的调用可以走到Derive的版本里面:

Base* d = new Derive();
d->Foo();

最最简单的思路:

(static_cast(d))->Foo();

怎么样,确实达到了要求,只不过……有些犯规的感觉。

那么换个思路,利用函数指针:

class Base
{
    public:
    void Foo()
    {
        if ( _pVFunc == NULL )
            cout<<"Base::Foo"<

略寒碜,而且那个_pVFunc语义非常不明确,美化一下:

class Base
{
    public:
    typedef void (Base::*V_FUNC)();
    void Foo() { (_caller->*_foo)(); }
    Base() { SetFunc( this, &Base::DoFoo ); }
    protected:
    void SetFunc( Base* caller, V_FUNC func) { _caller = caller; _foo = func; }
    Base* _caller;
    V_FUNC _foo;
    private:
    void DoFoo() { cout<<"Base::Foo"<

等等,这似乎完全不算是美化啊,依然寒碜到家——只是调用者和函数的关系更加明确了。指向成员函数的指针这种东东可读性真的不够好。目前为止穷尽我的脑细胞也就能想到上面这两类(如果第一种也算)方法来。用函数指针实现的版本虽然调用上令人满意,但实现上问题实在太多:指针类型要跟着函数原型走,新增一种其他参数、返回值的函数就要重新写一个;和类型绑定,无法扩展;SetFunc丑陋无比。

于是放狗发现StackOverflow上面有个帖子Can I get polymorphic behavior without using virtual functions?专门讨论这个话题。里面我所考虑的这些方法都有。

最值得注意的当然是James McNellis列出的两个方案,第一种也是和类型绑定,用了union存储函数指针,并且将cast部分专门提了一个wrapper类出来,总体来说可读性和实用性也就那样(他提到不能用std::function,因为这东西也是用虚函数实现)。但第二种非常cooool,利用宏定义和函数重载,加上boost的特性模拟了一个vtable出来,至于型别转换、函数映射都隐藏得非常好,使用的类只要在定义中一两行代码就可以上路了。

6 Responses to “不用虚函数机制实现运行时多态”

  1. Payoneer中国说道:

    这个网站是一个奇妙的网站。因此,我在这里提出一个建议:
    现在,在中国,你必须发送,并通过了世界上最好的汇款服务收钱的选项。注册,您将收到一个免费的借记卡,你可以从自动取款机直接拿钱。注册并免费获得25美元,第一次加油卡。中国Payoneer提供了超过200个国家,只有几个小时所支付的可能性。不要错过这个服务。

  2. Проверенный способ заработка в интернете от 7954 р. в сутки. Реальный заработок денег в сети http://ediqogobazas.ml/jty2说道:

    Самый быстрый способ заработка в интернете от 6962 rub. в день https://darknesstr.com/zarabotaymillion267395

  3. Как заработать в интернете с нуля от от 6643 рублей в сутки! Супер новая простая стратегия: https://klurl.nl/?u=JExSRypU说道:

    Очень быстрый способ заработка в интернете от 7169 rubley в день: https://darknesstr.com/millionrubley902762

  4. Jasonred说道:

    Republican politicians all over the country have repeated the Great Replacement theory
    A century-old racist theory reentered the political discourse around immigration and has become commonplace on the campaign trail as Republicans hope to retake control of Congress in November.

  5. RichardMip说道:

    Antibiotics are a medicine that stops bacterial growth by killing the bacteria. Common antibiotics include penicillin and ciprofloxacin. Antibiotic medicine bought online with or withooutt prescription – You can buy antibiotics without a prescription online from our shop to get them delivered straight to your doorstep.

  6. RichardMip说道:

    Neurontin (Gabapentin) is an anti-epileptic drug, also called an anticonvulsant. It affects chemicals and nerves in the body that are involved in the cause of seizures and some types of pain.
    Neurontin is used in adults to treat neuropathic pain (nerve pain) caused by herpes virus or shingles (herpes zoster).
    Special offer – BUY NEURONTIN ONLINE NOW and Get Discount for all Purchased! – No Prescription Required.
    Safe & Secure Payments. Fast & Free Delivery.
    Two Free Pills (Viagra or Cialis or Levitra) available With Every Order.