How to use dynamic_cast in if statement
How to use dynamic_cast in if statement
So I've got a simple task to do. There are 3 classes derived from one base class. They're quite simple and will be provided below.
What I need to do is create a new class called PolymorphicAnimal
, that'll be able to behave just as any other animal
derived from the Animal
base class.
To be exact, all they need to do is display the right text after method SoundOff
is called. I'm guessing I need to use dynamic_cast
here. My question is, what's the right syntax for using dynamic_cast
as an if
statement, and do all the derived classes need to have at least one virtual method as well?
PolymorphicAnimal
animal
Animal
SoundOff
dynamic_cast
dynamic_cast
if
#include "stdafx.h"
#include <iostream>
#include <string>
class Animal {
public:
virtual std::string SoundOff() = 0;
};
class Dog : public Animal {
std::string SoundOff() override { return "Woof"; }
};
class Cat : public Animal {
std::string SoundOff() override { return "Meow"; }
};
class Cow : public Animal {
std::string SoundOff() override { return "Muu"; }
};
class PolymorphicAnimal : public Animal {
std::string sound;
public:
PolymorphicAnimal(const Animal &a) {
if(std::dynamic_cast<Cat*>(a))
}
};
The line if(std::dynamic_cast...
generates compiler errors:
if(std::dynamic_cast...
syntax error '<', illegal token on the right side of ::
and expected an identifier
syntax error '<', illegal token on the right side of ::
expected an identifier
if(std::dynamic_cast<Cat*>(a))
@stetoc syntax error '<', illegal token on the right side of ::, and expected an indentifier (in the line with
dynamic_cast
)– Melvin Brooks
Jul 3 at 9:27
dynamic_cast
you cannot cast object to pointer, you need to basically add
&
before a
in your dynamic cast so you pass address of object– stetoc
Jul 3 at 9:29
&
a
Use
if(std::dynamic_cast<Cat*>(&a)
.– Peter
Jul 3 at 9:44
if(std::dynamic_cast<Cat*>(&a)
4 Answers
4
In C++ you can declare a variable in the conditional of an if
, which is a powerful feature that you can exploit here. So,
if
if (auto kitty = dynamic_cast<const Cat*>(&a)){
// kitty is not nullptr
}
Notes:
dynamic_cast
std::
dynamic_cast
bool
I was trying your code, and it wouldn't work, then I realized I'm missing
const
, and just then it worked. This is exactly what I've been looking for. Thank you!– Melvin Brooks
Jul 3 at 9:33
const
Also, just being curios, why wouldn't it work without
const
– Melvin Brooks
Jul 3 at 9:33
const
@MelvinBrooks: Out of interest, what is the syntax that didn't work?
– Bathsheba
Jul 3 at 9:38
not the
const auto kitty
, but const Cat
– Melvin Brooks
Jul 3 at 9:40
const auto kitty
const Cat
Ah I see, yes you need
<const Cat*>
in the dynamic_cast
since dynamic_cast
is not allowed to cast away const-ness, const_cast
is required for that, with all the cautions that go along with such a cast.– Bathsheba
Jul 3 at 9:41
<const Cat*>
dynamic_cast
dynamic_cast
const_cast
dynamic_cast
is almost always a hack.
dynamic_cast
Why don't you add another virtual method to Animal
, and then have Dog
, Cat
and Cow
override it in the usual way? Or don't you control these classes?
Animal
Dog
Cat
Cow
This is a task that usually comes on my exam and carries a nice amount of points for what it is, and the professor expects as to show that we know when and how to use
dynamic_cast
– Melvin Brooks
Jul 3 at 9:37
dynamic_cast
OK, well, if you have no choice... So now you know how, and the 'when' is ... 'never' :)
– Paul Sanders
Jul 3 at 9:39
͏+͏1͏͏͏͏͏͏͏͏͏͏͏͏͏ Nothing wrong with curve-ball answers if they contain excellent advice, which this one does.
– Bathsheba
Jul 3 at 9:44
@Bathsheba Thanks, I'm honoured. Curve-ball answers are a bit of a trademark of mine. Doesn't always work, but, well, you know.
– Paul Sanders
Jul 3 at 9:56
Whereas virtual methods or visitor might be more appropriated, you might use something like:
PolymorphicAnimal(const Animal &a) {
if (const auto* cat = std::dynamic_cast<const Cat*>(&a)) {
// use cat
} else if (const auto* dog = std::dynamic_cast<const Dog*>(&a)) {
// use dog
} // ...
}
It is very unclear what exactly the PolymorphicAnimal should do. Somehow you need to tell PolymorphicAnimal how to behave, right? So, I'm guessing it's more like a Factory than a derived class.
Something like this:
class PolymorphicAnimal : Animal
{
private:
Animal *animal;
public:
PolymorphicAnimal(int type)
{
if (type == Type_Cat) // Type_Cat is an enum for example
{
animal = new Cat();
}
// ...add other types here
}
std::string SoundOff()
{
return animal->SoundOff();
}
}
Normally, you shouldn't need to do if (something dynamic_cast something) in a normal program.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
whats the problem with
if(std::dynamic_cast<Cat*>(a))
?– stetoc
Jul 3 at 9:21