How can i cast to a derived class? The below approaches all give the following error:
Cannot convert from BaseType to DerivedType. No constructor could take the source type, or constructor overload resolution was ambiguous.
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
No, there is no built in conversion for this. You'll need to create a constructor, like you mentioned, or some other conversion method. Also, since BaseClass is not a DerivedClass, myDerivedObject will be null, andd the last line above will throw a null ref exception.
C++ Explicit type conversions Base to derived conversion Likewise, a reference to base class can be converted to a reference to derived class using static_cast . If the source type is polymorphic, dynamic_cast can be used to perform a base to derived conversion.
It is the process to create the derived class's pointer or reference from the base class's pointer or reference, and the process is called Upcasting. It means the upcasting used to convert the reference or pointer of the derived class to a base class.
Upcasting can cause object slicing when a derived class object is passed by value as a base class object, as in foo(Base derived_obj). The opposite process, converting a base-class pointer (reference) to a derived-class pointer (reference) is called downcasting. Downcasting is not allowed without an explicit type cast.
Think like this:
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.
Now looking back at your first statement:
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 !!!!
You should very rarely ever need to use dynamic cast.
This is why we have virtual methods:
void makeNoise(Animal& animal) { animal.DoNoiseMake(); } Dog dog; Cat cat; Duck duck; Chicken chicken; makeNoise(dog); makeNoise(cat); makeNoise(duck); makeNoise(chicken);
The only reason I can think of is if you stored your object in a base class container:
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.
But if you need to cast particular objects back to Dogs then there is a fundamental problem in your design. You should be accessing properties via the virtual methods.
barnYard[1]->DoNoiseMake();
dynamic_cast should be what you are looking for.
EDIT:
DerivedType m_derivedType = m_baseType; // gives same error
The above appears to be trying to invoke the assignment operator, which is probably not defined on type DerivedType and accepting a type of BaseType.
DerivedType * m_derivedType = (DerivedType*) & m_baseType; // gives same error
You are on the right path here but the usage of the dynamic_cast will attempt to safely cast to the supplied type and if it fails, a NULL will be returned.
Going on memory here, try this (but note the cast will return NULL as you are casting from a base type to a derived type):
DerivedType * m_derivedType = dynamic_cast<DerivedType*>(&m_baseType);
If m_baseType was a pointer and actually pointed to a type of DerivedType, then the dynamic_cast should work.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With