Acceptable example of when to use a dynamic

This question already has an answer here:

  • When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? 6 answers

  • @user997112

    [edit at bottom]

    Hello. Below we use a collection of random polymorphic pointers with common ancestor
    through the common interface.
    Additional work is done with one of the particular derived classes
    we need dynamic_cast or typeid to know this ....
    main function has the call
    then class declarations
    then the dynamic cast is at end
    delete of objects created with new is not shown

    #include <iostream>
    #include <algorithm>
    #include <random>
    #include <exception>
    using namespace std;
    
    int dynamic_test();
    int main()
    {
        cout << "Hello world!" << endl;
        dynamic_test();
        return 0;
    }
    

    ............

    class basex {
        public:
        virtual ~basex() {};
        virtual void work() const = 0;
    };
    class next1x : public basex {
        public:
        void work() const override {cout << "1";/*secret*/}
    };
    class next2x : public basex {
        public:
        void work() const override {cout << "2";/*secret*/}
    };
    class next3x : public basex {
        public:
        void work() const override {cout << "3";/*secret*/}
    };
    
    std::vector<basex *> secret_class_picker()
    {
        //pick classes with common base at random
        std::random_device rd;
        std::uniform_int_distribution<int>  ud(1,3);
        std::mt19937 mt(rd());
        std::vector<int> random_v;
        for (int i = 0; i < 22; ++i)
            random_v.push_back( ud(mt) );
        cout << "Random" << endl;
        for ( auto bq : random_v) //inspecting for human reader
            cout << bq << " ";
        std::vector<basex *> v;
        basex * bptr;
        for (auto bq : random_v) {
                switch(bq)
                {
    
                default: throw std::exception(); break;
                case 1: bptr = new next1x; break;
                case 2: bptr = new next2x; break;
                case 3: bptr = new next3x; break;
                }
    
                v.push_back(bptr);
        }
        cout << "Objects Created " << v.size() << endl;
        return v;
    
    }
    
    //this function demands a more derived class
    int special_work(const next3x *)
    {
        //elided
        cout <<"[!]";
        return 0;
    }
    
    int dynamic_test()
    {
        std::vector<basex *> v = secret_class_picker();//delete these pointer later
        cout <<"Working with random polymorphic pointers"<<endl;
        for (const auto bq : v)
        {
            bq->work();//polymorphic
            next3x * ptr = dynamic_cast<next3x *>(bq);
            if (nullptr != ptr) special_work(ptr); //reserved for particular type
        }
        return 0;
    }
    

    ...................... alternative

    int dynamic_static_typeid()
    {
        std::vector<basex *> v = secret_class_picker();
        cout <<"Working with random polymorphic pointers"<<endl;
        int k(0);
        for (const auto bq : v)
        {
            bool flipflop = (k % 2) == 0;
            bq->work();//polymorphic
            //cout << "[*]"<< typeid(*bq).name();//dereference
    
            if (flipflop) {
                next3x * dc_ptr = dynamic_cast<next3x *>(bq);//not constant time in general
                if (nullptr != dc_ptr) {
                    special_work(dc_ptr); //reserved for particular type
                    ++k;
                }
            }
            else {
                if (typeid(next3x) == typeid(*bq)){//constant time
                    auto sc_ptr = static_cast<next3x *>(bq);//constant time
                    special_work(sc_ptr);
                    ++k; cout <<"[sc]";
                }
            }
            cout << endl;
        }
        return 0;
    }
    
    链接地址: http://www.djcxy.com/p/28706.html

    上一篇: 演员表或C风格类型演员

    下一篇: 什么时候使用动态的可接受示例