05 January 2023

C++ 核心指南目录

C.148: Use dynamic_cast to a pointer type when failure to find the required class is considered a valid alternative

理由

dynamic_cast 允许对转换结果的指针进行测试,是否指向有效的多态对象。因为无法找到合适的类型只会返回一个空值,所以可以在运行时进行测试判断。这样就能在写代码的时候进行判断,根据结果选择不同的执行路径。

这里与C.147不同。C.147 会抛出异常,无法进行条件判断。

例子

以下例子 add 函数会把形状放到形状保管器里。不同形状还会添加到形状视图中。先对形状进行动态类型转换,根据转换结果装入不同的视图。

void add(Shape* const item)
{
    // Ownership is always taken
    owned_shapes.emplace_back(item);

    // Check the Geometric_attributes and add the shape to none/one/some/all of the views

    if (auto even = dynamic_cast<Even_sided*>(item))
    {
        view_of_evens.emplace_back(even);
    }

    if (auto trisym = dynamic_cast<Trilaterally_symmetrical*>(item))
    {
        view_of_trisyms.emplace_back(trisym);
    }
}

注意

进行动态类型转换的时候,如果无法找到对应的类型,就会返回一个空值,如果对空值进行取值访问就会导致未定义行为。所以必须考虑空值的情况,进行判断测试。

强化

  • (复杂)只有对动态类型转换的结果进行空值判断后才能取值,不然抛出警告。