我如何投射到派生类?以下方法都会出现以下错误:
无法从BaseType转换为DerivedType.没有构造函数可以采用源类型,或构造函数重载解析是不明确的.
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
Run Code Online (Sandbox Code Playgroud)
Mar*_*ork 127
这样想:
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.
Run Code Online (Sandbox Code Playgroud)
现在回顾你的第一个声明:
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 !!!!
Run Code Online (Sandbox Code Playgroud)
你应该很少需要使用动态强制转换.
这就是为什么我们有虚拟方法:
void makeNoise(Animal& animal)
{
animal.DoNoiseMake();
}
Dog dog;
Cat cat;
Duck duck;
Chicken chicken;
makeNoise(dog);
makeNoise(cat);
makeNoise(duck);
makeNoise(chicken);
Run Code Online (Sandbox Code Playgroud)
我能想到的唯一原因是你是否将对象存储在基类容器中:
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.
Run Code Online (Sandbox Code Playgroud)
但是如果你需要将特定的物体投射回狗身上,那么你的设计就会遇到根本问题.您应该通过虚拟方法访问属性.
barnYard[1]->DoNoiseMake();
Run Code Online (Sandbox Code Playgroud)
dynamic_cast应该是你想要的.
编辑:
DerivedType m_derivedType = m_baseType; // gives same error
Run Code Online (Sandbox Code Playgroud)
上面似乎试图调用赋值运算符,它可能没有在DerivedType类型上定义并接受一种BaseType.
DerivedType * m_derivedType = (DerivedType*) & m_baseType; // gives same error
Run Code Online (Sandbox Code Playgroud)
您在这里是正确的路径,但dynamic_cast的使用将尝试安全地转换为提供的类型,如果失败,将返回NULL.
在这里继续记忆,试试这个(但是请注意,当你从基类型转换为派生类型时,强制转换将返回NULL):
DerivedType * m_derivedType = dynamic_cast<DerivedType*>(&m_baseType);
Run Code Online (Sandbox Code Playgroud)
如果m_baseType是一个指针并实际指向DerivedType类型,那么dynamic_cast应该可以工作.
希望这可以帮助!
您不能将基础对象强制转换为派生类型 - 它不属于该类型.
如果您有一个指向派生对象的基类型指针,那么您可以使用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
Run Code Online (Sandbox Code Playgroud)