Reputation: 35
I simply created two derived class from a base class. Then created an object of a derived class and converted into base class. Then from the base class, i converted to derived class number two, I was hoping it won't work, but it did. Can someone please explain me how below code is working... And How do I prevent this from happening...
PS: Now edited the Program to make bit more sense. Also this is the situation I want to avoid if possible:
class Animal
{
public:
Animal() { std::cout << "I am an animal\r\n"; };
virtual void makeSound() = 0;
~Animal() = default;
};
class Cat : public Animal
{
public:
Cat() { std::cout << "I am a Cat\r\n"; };
void makeSound() final { std::cout << "Meaow\r\n"; }
~Cat() = default;
};
class Dog : public Animal
{
public:
Dog() { std::cout << "I am a Dog\r\n"; };
void makeSound() final { std::cout << "Bark\r\n"; }
~Dog() = default;
};
template<typename baseType, typename derivedType>
std::unique_ptr<derivedType> dynamicConvert(std::unique_ptr<baseType> baseObj)
{
auto tmp = dynamic_cast<derivedType*>(baseObj.get());
std::unique_ptr<derivedType> derivedPointer;
if (tmp != nullptr)
{
baseObj.release();
derivedPointer.reset(tmp);
}
return derivedPointer;
}
int main()
{
auto cat = std::make_unique<Cat>();
auto base = dynamicConvert<Cat, Animal>(std::move(cat));
base->makeSound();
auto dog = dynamicConvert<Animal, Dog>(std::move(base));
dog->makeSound();
return 0;
}
Output:
I am an animal
I am a Cat
Meaow
Bark
Upvotes: 1
Views: 55
Reputation: 63114
You can't, that's part of the contract with static_cast
. It is resolved at compile time, and thus will not check at runtime that you didn't make a mistake: casting to the wrong type just triggers UB.
Use dynamic_cast
when you want runtime-checked conversions.
Upvotes: 3