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

标签 c++ inheritance polymorphism dynamic-cast

<分区>

派生类型转换的真正可接受的用法示例是什么?我一直认为它们只在实现“hacks”时使用,但如果不是这种情况,有人可以给出一个可接受的例子来说明何时使用吗?

最佳答案

@user997112

[在底部编辑]

你好。下面我们使用一组具有共同祖先的随机多态指针
通过通用接口(interface)。
使用特定的派生类之一完成额外的工作
我们需要 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;
}

......................替代

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

关于c++ - 何时使用 dynamic_cast 的可接受示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20223565/

相关文章:

C++11:lambda 捕获以什么顺序被破坏?

c++ - 类型索引元组

c# - 如何在C#.Net中使用反射(指定多少层次结构)来获取类的属性?

继承

java - 安全的多态性实践?

c++ - 捕获到缓冲区 QT

c++ - 对于 SQLCHAR 类型参数,ODBC SQLBindParameter 的 ColumnSize 参数可以是 strlen(param) + 1 吗?

javascript - 在 Odoo 10 中继承 POS Javascript 函数

c++ - 如何在不同内核之间正确共享运行时创建的多态数据?嵌入式C++

c++ - 重载运算符*以获取对另一个类实例的引用