简体   繁体   中英

Polymorphic behaviour without virtual

I this a good implementation for this simple inheritance not using any virtual functions.

Why I would like this: Avoid virtual inheritance in performance crititcal code. A boost::variant could help here certainly, but I want only standard c++ stuff :-)

I refer also to this answer Link

#include <iostream>
using namespace std;

struct C;
struct B;

class A{
    public:
    A(int r): type(r){}
    int type;
    void deleter();
    protected:
    ~A(){std::cout << "DTOR A" << std::endl;}
};

class B: public A{
    public:
    B():A(1){};
    ~B(){std::cout << "DTOR B" << std::endl;}
};

class C: public A{
    public:
    C():A(2){};
    ~C(){std::cout << "DTOR B" << std::endl;}
};

void A::deleter(){
     if(type==1){
        delete static_cast<B* const>(this);
    }else if(type==2){
        delete static_cast<C* const>(this);
    }
}

int main(){
      A * a = new B();
      a->deleter();
}

I want to use the base pointer a . The main problem is what to do when we want to delete a . I simply prohibited that by making the DTOR of A protected. So the only way of using this construct is to call a.deleter() to safely delete a bas class pointer. Is this safe and a good implementation or is there a better approach?

http://ideone.com/pd88xy

You've cited a guideline "Avoid virtual inheritance in performance crititcal code". It's not a bad guideline, but it isn't the best wording.

The real rule is " Avoid runtime polymorphism in performance crititcal code ". Runtime polymorphism causes a performance hit. The compiler can't optimize across functions if it doesn't know the exact function being called ahead of time. (Branch prediction helps, but still is nowhere near as good as inlining-dependent optimizations)

To get both high performance and polymorphism, hoist the polymorphism outside of any loops. If the only polymorphic calls are for large operations, you don't pay the price of polymorphism very often.

Templates (compile-time polymorphism) can help compose the small operations without code duplication. Then you use a dynamic dispatch technique to pick one of the highly optimized template instantiations. At that point which dynamic dispatch technique you use doesn't much matter. Virtual calls, type erasure in std::function , or your own table of function pointers. Because the dynamic dispatch operation is small compared to the actual work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM