何时使用dynamic_cast的可接受示例?

时间:2013-11-26 17:10:24

标签: c++ inheritance polymorphism dynamic-cast

衍生演员阵容的真实可接受使用范例是什么?我一直以为它们只在实施“黑客”时使用,但如果不是这样,那么有人可以给出一个可以接受的例子吗?

1 个答案:

答案 0 :(得分:1)

@ user997112

[在底部编辑]

您好。下面我们使用一组具有共同祖先的随机多态指针 通过共同的界面 使用特定派生类之一进行额外的工作 我们需要dynamic_cast或typeid来了解这一点.... 主要功能有呼叫
然后是阶级声明
然后动态演员表结束了 删除用new创建的对象未显示

#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;
}