【问题标题】:Identifying derived class type from a base class从基类中识别派生类类型
【发布时间】:2014-04-15 00:17:51
【问题描述】:

在这种情况下,类 DeriA 和 DeriB 继承自 Base:

class Base
class DeriA : public Base
class DeriB : public Base

std::list<Base> objects;

是否可以检查从对象列表的每个成员继承的类类型? 我尝试在 try/catch 语句中使用 static_cast 以检查对象的某个成员是否为特定类型,如下所示:

try
{
    DeriA tempA = static_cast<DeriA>(*objects_iterator);
    std::cout << "Found A" << std::endl;
} catch(std::bad_cast e)
{
    // Dealing with the exception
    std::cout << "Found B" << std::endl;
}

但是,无论被访问的对象是 DeriA 还是 DeriB,这始终会输出“Found A”。谁能帮忙解释一下为什么?

【问题讨论】:

  • 并非如此,因为您的列表包含 Base 对象。因此,除非派生类型将Base 的成员设置为您可以检查的某个值,否则您就不走运了。但总的来说,这表明您需要重新设计。
  • 另一个问题是你的继承是私有的,所以派生类型不是Base。我认为这只是一个错字,并且您打算使用公共继承。
  • 确实是错字,谢谢
  • 您可能想了解object slicing,这可能是存储在列表中的对象的问题。
  • 为什么该代码甚至可以编译? DeriA 是否从 Base 定义了转换构造函数?此外,afaik bad_cast 仅在转换引用时由 dynamic_cast 抛出,而不是 static_cast。

标签: c++ inheritance casting static-cast


【解决方案1】:

如果你有一个Base* 指针,你可以dynamic_cast&lt;DeriA*&gt;。如果不是DeriA,结果将是强制转换对象或NULL。

但是,您正在处理价值观。您存储在列表中的Base(不是Base*)始终只是Base,而不是派生对象。如果你曾经有一个DeriA,你可能会在某个时候切掉其余部分。

【讨论】:

    【解决方案2】:

    从我看到的一些小例子来看,大多数使用 std::bad_cast 异常的都是使用 dynamic_cast。看看这个例子,看看 dynamic_cast 是否可以帮助你。 dynamic_cast 需要具有多态函数,但你会弄清楚的。

    http://en.cppreference.com/w/cpp/types/bad_cast

    -AP_

    【讨论】:

      【解决方案3】:

      不,你不能正确地做到这一点。 C++ 没有内置的运行时类型信息的概念,因此不可能使用静态类型转换来看看会发生什么。

      一些编译器虽然实现了一个(可怕的)RTTI 系统,但它允许您使用 dynamic_cast。 然而,大多数系统上的 RTTI 都有不想要的副作用,导致 Qt 等大型框架实现自己的 MACRO Magic RTTI 系统。

      【讨论】:

        猜你喜欢
        • 2012-09-22
        • 2011-01-05
        • 1970-01-01
        • 2015-03-30
        • 2014-03-22
        • 2020-06-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-08
        相关资源
        最近更新 更多