C ++转换为派生类

我怎样才能投射到派生类? 下面的方法都给出了以下错误:

无法从BaseType转换为DerivedType。 没有构造函数可以采取源types,或构造函数重载parsing是模糊的。

BaseType m_baseType; DerivedType m_derivedType = m_baseType; // gives same error DerivedType m_derivedType = (DerivedType)m_baseType; // gives same error DerivedType * m_derivedType = (DerivedType*) & m_baseType; // gives same error 

这样想:

 class Animal { /* Some virtual members */ }; class Dog: public Animal {}; class Cat: public Animal {}; Dog dog; Cat cat; Animal& AnimalRef1 = dog; // Notice no cast required. (Dogs and cats are animals). Animal& AnimalRef2 = cat; Animal* AnimalPtr1 = &dog; Animal* AnimlaPtr2 = &cat; Cat& catRef1 = dynamic_cast<Cat&>(AnimalRef1); // Throws an exception AnimalRef1 is a dog Cat* catPtr1 = dynamic_cast<Cat*>(AnimalPtr1); // Returns NULL AnimalPtr1 is a dog Cat& catRef2 = dynamic_cast<Cat&>(AnimalRef2); // Works Cat* catPtr2 = dynamic_cast<Cat*>(AnimalPtr2); // Works // This on the other hand makes no sense // An animal object is not a cat. Therefore it can not be treated like a Cat. Animal a; Cat& catRef1 = dynamic_cast<Cat&>(a); // Throws an exception Its not a CAT Cat* catPtr1 = dynamic_cast<Cat*>(&a); // Returns NULL Its not a CAT. 

现在回头看看你的第一个陈述:

 Animal animal = cat; // This works. But it slices the cat part out and just // assigns the animal part of the object. Cat bigCat = animal; // Makes no sense. // An animal is not a cat!!!!! Dog bigDog = bigCat; // A cat is not a dog !!!! 

你应该很less需要使用dynamic投射。
这就是为什么我们有虚拟方法:

 void makeNoise(Animal& animal) { animal.DoNoiseMake(); } Dog dog; Cat cat; Duck duck; Chicken chicken; makeNoise(dog); makeNoise(cat); makeNoise(duck); makeNoise(chicken); 

我能想到的唯一原因是如果你将你的对象存储在一个基类容器中:

 std::vector<Animal*> barnYard; barnYard.push_back(&dog); barnYard.push_back(&cat); barnYard.push_back(&duck); barnYard.push_back(&chicken); Dog* dog = dynamic_cast<Dog*>(barnYard[1]); // Note: NULL as this was the cat. 

但是如果你需要将特定的对象抛回到狗身上,那么在你的devise中就存在一个基本的问题。 您应该通过虚拟方法访问属性。

 barnYard[1]->DoNoiseMake(); 

dynamic_cast应该是你在找什么。

编辑:

 DerivedType m_derivedType = m_baseType; // gives same error 

上述似乎试图调用赋值运算符,这可能没有定义typesDerivedType并接受一种BaseType。

 DerivedType * m_derivedType = (DerivedType*) & m_baseType; // gives same error 

你在这里是正确的path,但dynamic_cast的使用将尝试安全地转换为提供的types,如果失败,将返回一个NULL。

在这里回忆一下,试试这个(但是注意,当你从基types转换为派生types时,转换将返回NULL):

 DerivedType * m_derivedType = dynamic_cast<DerivedType*>(&m_baseType); 

如果m_baseType是一个指针,实际上指向一个DerivedTypetypes,那么dynamic_cast应该工作。

希望这可以帮助!

您不能将基础对象转换为派生types – 它不是这种types。

如果您有一个指向派生对象的基types指针,那么您可以使用dynamic_cast强制转换该指针。 例如:

 DerivedType D; BaseType B; BaseType *B_ptr=&B BaseType *D_ptr=&D;// get a base pointer to derived type DerivedType *derived_ptr1=dynamic_cast<DerivedType*>(D_ptr);// works fine DerivedType *derived_ptr2=dynamic_cast<DerivedType*>(B_ptr);// returns NULL 

首先 – 沮丧的先决条件是你正在施放的对象是你正在施放的types。 使用dynamic_cast进行投射将在运行时检查这个条件(假设铸造的对象有一些虚函数)并抛出bad_cast或在失败时返回NULL指针。 编译时间转换不会检查任何内容,只会导致tu未定义的行为,如果这个先决条件不成立。
现在分析你的代码:

 DerivedType m_derivedType = m_baseType; 

这里没有铸造。 您正在创buildDerivedTypetypes的新对象,并尝试使用m_baseTypevariables的值对其进行初始化。

下一行不太好:

 DerivedType m_derivedType = (DerivedType)m_baseType; 

在这里,您正在创build一个使用m_baseType值初始化的DerivedTypetypes的临时值。

最后一行

 DerivedType * m_derivedType = (DerivedType*) & m_baseType; 

应该进行编译,前提是BaseTypeDerivedType的直接或间接公共基类。 无论如何它有两个缺陷:

  1. 您使用不推荐的C风格转换。 这种演员的正确方法是
    static_cast<DerivedType *>(&m_baseType)
  2. 铸造对象的实际types不是DerivedType(因为它被定义为BaseType m_baseType;所以任何对m_derivedType指针的使用都会导致未定义的行为。