2016-05-12 182 views
3

我试图将基类对象转换为派生类对象dynamic_cast,但dynamic_cast返回null。是否有可能使用dynamic_cast倒置?使用dynamic_cast向下转换返回null

struct A { 
    virtual ~A() {} 
}; 

struct B : A {}; 


int main() 
{ 
    A* a = new A(); 

    B* b = dynamic_cast<B*>(a); 
    if(b){ 
     std::cout << "b has value" << std::endl; 
    }else{ 
     std::cout << "no value" << std::endl; 
    } 
} 

此代码打印出“没有值”。

+0

FYI铸造*向下*继承链被称为向下铸造。 – NathanOliver

+2

你不能从A那里得到一个B,这个语言会怎么做,例如, B实例拥有比A实例更多的数据成员? –

+3

你不能将'a'降为'B *',因为它不指向'B',它指向'A':'A'不是'B'。然而,你可以将'B *'转换为'A *',因为'B *'会指向一个B,这个“是一个”A(继承的定义) – KABoissonneault

回答

14

因为a实际上指向的是A,而不是B,那么dynamic_cast将会失败。

是否可以使用dynamic_cast向下倾倒?

是的,你可以,例如,如果a指向B准确地说,

A* a = new B; 
B* b = dynamic_cast<B*>(a); 

参见http://en.cppreference.com/w/cpp/language/dynamic_cast

5)如表达式是一个指针或引用一个多态型Base和NEW_TYPE是一个指针或引用派生一个运行的类型执行时间检查:

a)检查由表达式指出/识别的派生最多的对象。如果在该对象中,表达式点/指的是派生的公共基础,并且如果只有一个派生类型的子对象从由该表达式指向/标识的子对象派生,那么抛出的结果指向/指向该派生子对象。 (这被称为 “垂头丧气”。)

...

c)否则,运行时检查失败。如果在指针上使用dynamic_cast,则返回类型为new_type的空指针值。如果在引用上使用它,则抛出异常std::bad_cast

+0

如果基础对象能够使用'dynamic_cast'已经删除了默认的ctor,只能用静态函数'create'创建? – Herrgott

+0

@Herrgott是的。 'dynamic_cast'与指针和引用一起工作,它不涉及基类的默认构造函数。 – songyuanyao

4

即每个设计。当您想要测试指向基类对象的指针是否实际指向子类时,将使用dynamic_cast。如果它是一个子类对象,那么dynamic_cast会给你一个有效的指针,如果它不是,你只会得到一个nullptr

当您创建A类对象,并且A不是B的子类时,dynamic_cast通常返回空指针。